{"record":{"id":"7c5977adef51653c","repo":"slackhq/nebula","slug":"nil-header","errorCode":null,"errorMessage":"nil header","messagePattern":"nil header","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"header/header.go","lineNumber":136,"sourceCode":"\t\th.Version, h.TypeName(), h.SubTypeName(), h.Reserved, h.RemoteIndex, h.MessageCounter)\n}\n\n// MarshalJSON creates a json string representation of a header\nfunc (h *H) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(m{\n\t\t\"version\":        h.Version,\n\t\t\"type\":           h.TypeName(),\n\t\t\"subType\":        h.SubTypeName(),\n\t\t\"reserved\":       h.Reserved,\n\t\t\"remoteIndex\":    h.RemoteIndex,\n\t\t\"messageCounter\": h.MessageCounter,\n\t})\n}\n\n// Encode turns header into bytes\nfunc (h *H) Encode(b []byte) ([]byte, error) {\n\tif h == nil {\n\t\treturn nil, errors.New(\"nil header\")\n\t}\n\n\treturn Encode(b, h.Version, h.Type, h.Subtype, h.RemoteIndex, h.MessageCounter), nil\n}\n\n// Parse is a helper function to parses given bytes into new Header struct\nfunc (h *H) Parse(b []byte) error {\n\tif len(b) < Len {\n\t\treturn ErrHeaderTooShort\n\t}\n\t// get upper 4 bytes\n\th.Version = uint8((b[0] >> 4) & 0x0f)\n\t// get lower 4 bytes\n\th.Type = MessageType(b[0] & 0x0f)\n\th.Subtype = MessageSubType(b[1])\n\th.Reserved = binary.BigEndian.Uint16(b[2:4])\n\th.RemoteIndex = binary.BigEndian.Uint32(b[4:8])\n\th.MessageCounter = binary.BigEndian.Uint64(b[8:16])","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/header/header.go#L118-L154","documentation":"Ad-hoc errors.New(\"nil header\") returned by H.Encode when the header receiver h is nil. It is a nil-receiver guard: encoding a packet header requires a non-nil *H, and calling Encode on a nil header (e.g. a zero-value packet struct) aborts before bytes are written.","triggerScenarios":"Calling Encode on a nil *H — e.g. a header variable that was never populated, or a function returning (*H, error) whose nil result is passed straight to Encode (as in the TestCloseTunnelAuthenticated call path).","commonSituations":"A build/parse step earlier failed silently and left the header nil; logic error where the header struct was conditionally created; test harness forgetting to initialize the header.","solutions":["Initialize the header before encoding — ensure the code path always constructs a valid *H","Check the error from any earlier Parse/build step that produced the header; do not pass a nil result onward","Add a nil check in the caller before invoking Encode"],"exampleFix":"// before\nvar h *header.H\nb, err := h.Encode(buf) // \"nil header\"\n// after\nh := &header.H{Version: header.Version, Type: header.Message, Subtype: 0}\nb, err := h.Encode(buf)","handlingStrategy":"validation","validationCode":"if h == nil {\n    return fmt.Errorf(\"cannot encode nil header\")\n}","typeGuard":"func headerReady(h *header.H) bool {\n    return h != nil\n}","tryCatchPattern":"b, err := h.Encode(buf)\nif err != nil {\n    return fmt.Errorf(\"header encode: %w\", err)\n}","preventionTips":["Always check errors from steps that produce the *H before encoding","Construct headers via a helper that guarantees a non-nil result","Guard with a nil check in callers that receive (*H, error)"],"tags":["header","nil-pointer","packet-encoding"],"backgroundTag":"nil-value-guard","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}