Runtime Error 63: “Bad record number,” explained and fixed

Error 63, “Bad record number”, fires when a Get or Put is given a record number that cannot be used: zero, negative, or beyond the range the file and mode permit. Records in VBA random access are numbered from 1, and a surprising share of error 63s are off-by-one bugs where an index counted from 0 (an array index, a list position) was used directly as a record number. The file is not corrupt; the address handed to the read or write is invalid.

For people who just run the program

  1. Expect it around “first” and “last” records. Jumping to the first item, the last item, or an item in an empty list are the operations that produce invalid record numbers.
  2. Check whether the data set is empty. Asking for record 1 in a file that has no records yet, often a brand-new installation or a cleared database, is the everyday version of this error.
  3. Note the exact navigation or search that triggered it. Record-number bugs live in specific lookups; the lookup you ran is the maintainer's reproduction case.
  4. Do not delete the data file to “reset” it. The number is computed by the code; a fresh file usually reproduces the same failure at the same step.

For people who write the code

  1. Add 1 when crossing from 0-based worlds. Array indices, ListIndex values, and loop counters starting at 0 must be shifted before they address records:
  2. recNo = listBox.ListIndex + 1   ' ListIndex is 0-based; records are 1-based
    Get #fn, recNo, rec             ' without the +1, the first item is error 63
  3. Validate against the record count. The count is LOF(fn) \ recordLength. A requested number above the count on a Get, or below 1 anywhere, should be rejected with a clear message before the statement runs.
  4. Beware computed numbers from data. An ID read from a record and later used as a record number assumes IDs are dense and start at 1. After deletions they are not. Keep an index, or search by key, instead of treating keys as addresses.
Put with a huge record number does not raise error 63; it creates a sparse file. Writing record 1,000,000 into an empty file succeeds and allocates a file with a million blank records. The dangerous direction is not always the one that errors.

If it still happens

If the number is in range and error 63 persists, verify the file was opened For Random and not For Binary (binary access uses byte positions, and the same number means a different thing), and confirm the record number variable is not overflowing: a Long computation stored into an Integer wraps into a negative, invalid number.

Common questions

Why is record 0 invalid? VBA numbers random-access records starting at 1. Zero is reserved in Get and Put to mean “the next record after the current position,” so passing a literal 0 from a 0-based index is both common and wrong.

Can error 63 mean the file is corrupt? Not by itself. It reports an invalid address for the operation. Corruption shows up as wrong data read successfully, or as error 59 when record boundaries stop lining up.

Related errors

Runtime Error 59 · Runtime Error 62 · Runtime Error 52