Runtime Error 59: “Bad record length,” explained and fixed

Error 59, “Bad record length”, belongs to random-access file I/O. When a file is opened For Random with a record length, every Put and Get must transfer exactly that many bytes. If the variable being written is longer or shorter than the declared length, VBA raises error 59. The classic cause is a user-defined type whose real size drifted from the number typed into the Open statement, often after someone edited the type and not the length.

For people who just run the program

  1. Expect this in older data-driven programs. Random-access files with fixed records are a legacy pattern; the error means the program and its data file disagree about the record layout.
  2. Do not let the program create a fresh data file and assume the problem is solved. If the layout changed, old records need conversion, not abandonment; the existing file holds the real data.
  3. Note whether it began after a program update. A new version expecting a different record size against an old file is the most common real-world setup for error 59.
  4. Back up the data file before any repair attempt. Record-layout repairs rewrite the file; the backup is the only way back.

For people who write the code

  1. Compute the length from the type, never type it from memory. Open with Len = Len(recordVariable) so the declared length cannot drift from the type's actual size:
  2. Type CustomerRec
        ID As Long
        Name As String * 30
        Balance As Currency
    End Type
    Dim rec As CustomerRec
    Open path For Random As #fn Len = Len(rec)   ' not a hand-typed number
  3. Remember variable-length strings break the math. A user-defined type used for random access must use fixed-length strings (String * 30). A variable-length String field stores a pointer-sized placeholder in the file buffer, not the text, and the byte count stops matching reality.
  4. Check alignment padding. VBA may insert padding bytes between fields of a type. Two types with identical fields declared in different orders can have different sizes; Len() on the actual variable is the only trustworthy measure.
  5. Version the format. If a record layout must change, write a version marker and a converter. Error 59 against every existing installation's files is what happens when the layout changes silently.
Error 59 on a Get corrupts nothing, but guessing a new length and continuing does. Reading records at the wrong length scrambles every field boundary from that point on. Stop, establish the true record size from the writing code, and convert deliberately.

If it still happens

If Len() matches and error 59 still fires, the variable being Put may be a Variant containing a string: the transferred byte count then depends on content, not layout. Convert to a typed variable or fixed-length string before the Put so the count is stable.

Common questions

What is a record length in a random-access file? The fixed number of bytes each record occupies. Random access works by arithmetic: record N starts at byte (N - 1) times the record length. If the length is wrong, every record after the first is read from the wrong offset.

Why did error 59 start after editing the type? Because the Open statement usually still holds the old length as a typed-in number. Adding a field changed the type's size; the stale length in Open is now wrong for every Put and Get.

Related errors

Runtime Error 54 · Runtime Error 63 · Runtime Error 62