nats-io/nats-server · error
ErrNoActiveEntry
ErrNoActiveEntry
Error message
archive: no active entry
What it means
ErrNoActiveEntry means Writer.Write was called without an open archive entry. Every payload byte must belong to an entry started by WriteHeader; after an entry's declared size is fully written, the Writer clears its internal header, so further Writes are rejected. It is an API-misuse error on the write side of the archive format.
Source
Thrown at server/archive/archive.go:34
import (
"bufio"
"encoding/binary"
"errors"
"io"
)
const MagicBytes = "NATSARC1"
// maxNameLen bounds the entry name length accepted when reading an archive,
// avoiding an unbounded allocation on corrupt or malicious input. The name is
// the only variable-length field read directly from the stream.
const maxNameLen = 1 << 20
var (
ErrClosed = errors.New("archive: closed")
ErrInvalidArchive = errors.New("archive: invalid archive stream")
ErrIncompleteEntry = errors.New("archive: entry not fully written")
ErrNoActiveEntry = errors.New("archive: no active entry")
ErrWriteTooLong = errors.New("archive: write exceeds declared entry size")
ErrNilHeader = errors.New("archive: nil header")
ErrNegativeEntrySize = errors.New("archive: negative entry size")
)
// Header describes one archive entry.
//
// On the wire each entry is the encoded header fields followed by the payload.
// HeaderSize and PayloadSize describe how that payload is split (e.g. message
// headers vs. body); the payload length is their sum and is not stored
// separately. Sequence is always encoded, with 0 meaning "unset".
type Header struct {
Name string
HeaderSize int64
PayloadSize int64
Timestamp int64
Sequence uint64
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Call WriteHeader with a valid Header before every run of Write calls.
- Match Write calls 1:1 with entries: stop writing once you've written HeaderSize+PayloadSize bytes for the current entry.
- If bytes must precede the first entry, wrap a separate io.Writer for them; the archive stream itself must start with entries (the Writer emits the magic on the first WriteHeader).
- Track a 'current entry open' flag in your code mirroring a.header != nil.
Example fix
// before
w := archive.NewWriter(f)
w.Write(payload) // ErrNoActiveEntry
// after
w := archive.NewWriter(f)
if err := w.WriteHeader(&archive.Header{Name: "entry", HeaderSize: 0, PayloadSize: int64(len(payload))}); err != nil { return err }
if _, err := w.Write(payload); err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
// guard your own write helper
func writeEntry(w *archive.Writer, h *archive.Header, payload []byte) error {
if h == nil { return errors.New("nil header") }
if err := w.WriteHeader(h); err != nil { return err }
_, err := w.Write(payload)
return err
} Try / catch
if _, err := w.Write(p); err != nil {
if errors.Is(err, archive.ErrNoActiveEntry) {
return fmt.Errorf("Write called outside an entry; call WriteHeader first")
}
return err
} Prevention
- Never hand the archive Writer to code expecting a raw io.Writer; wrap it in an entry-scoped writer that asserts WriteHeader was called.
- Stop writing as soon as the declared payload bytes are consumed — the Writer clears its entry at remaining==0.
- Structure code as one function per entry: WriteHeader, write payload, return.
When it happens
Trigger: Writer.Write(p) called before any WriteHeader; Write called after the current entry's remaining bytes reached 0 (header auto-cleared, e.g. a zero-size entry or after writing the exact declared payload); Write called on a brand-new Writer with only a stale header pointer.
Common situations: Wrapping the Writer in an io.MultiWriter or passing it where an io.Writer is expected and writing preamble/metadata bytes outside of any entry; a caller that keeps writing after the payload loop ended (off-by-one or trailing newline flush); reusing a Writer variable whose last entry already completed.
Related errors
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/87ce94abaf1e4d00.
Report an issue: GitHub.