{"record":{"id":"d537a12f1768c457","repo":"slackhq/nebula","slug":"encoded-encryptionmetadata-was-nil","errorCode":null,"errorMessage":"encoded EncryptionMetadata was nil","messagePattern":"encoded EncryptionMetadata was nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/crypto.go","lineNumber":206,"sourceCode":"\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid curve: %v\", curve)\n\t}\n}\n\n// UnmarshalNebulaEncryptedData will unmarshal a protobuf byte representation of a nebula cert into its\n// protobuf-generated struct.\nfunc UnmarshalNebulaEncryptedData(b []byte) (*NebulaEncryptedData, error) {\n\tif len(b) == 0 {\n\t\treturn nil, fmt.Errorf(\"nil byte array\")\n\t}\n\tvar rned RawNebulaEncryptedData\n\terr := proto.Unmarshal(b, &rned)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif rned.EncryptionMetadata == nil {\n\t\treturn nil, fmt.Errorf(\"encoded EncryptionMetadata was nil\")\n\t}\n\n\tif rned.EncryptionMetadata.Argon2Parameters == nil {\n\t\treturn nil, fmt.Errorf(\"encoded Argon2Parameters was nil\")\n\t}\n\n\tparams, err := unmarshalArgon2Parameters(rned.EncryptionMetadata.Argon2Parameters)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tned := NebulaEncryptedData{\n\t\tEncryptionMetadata: NebulaEncryptionMetadata{\n\t\t\tEncryptionAlgorithm: rned.EncryptionMetadata.EncryptionAlgorithm,\n\t\t\tArgon2Parameters:    *params,\n\t\t},\n\t\tCiphertext: rned.Ciphertext,\n\t}","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/crypto.go#L188-L224","documentation":"After protobuf unmarshalling, RawNebulaEncryptedData.EncryptionMetadata must be present - it carries the Argon2 parameters and nonce needed for decryption. A decoded message with EncryptionMetadata nil means the serialized blob lacked the metadata sub-message, so decryption cannot proceed.","triggerScenarios":"Calling UnmarshalNebulaEncryptedData with protobuf bytes that parse but contain no EncryptionMetadata field - e.g. a hand-built or partially serialized RawNebulaEncryptedData, or bytes of a different message type that happen to parse.","commonSituations":"Constructing NebulaEncryptedData manually in tests and forgetting to set EncryptionMetadata; deserializing a truncated or wrong-version blob; passing an unrelated protobuf message by mistake.","solutions":["Ensure the encryption side populated EncryptionMetadata (via EncryptionMetadata in NebulaEncryptedData) before marshalling; re-encrypt the data with the standard EncryptAndMarshal* helpers","Verify the blob is a NebulaEncryptedData message and not truncated or a different protobuf type","Regenerate the encrypted artifact with the current library version"],"exampleFix":"// before\nned := &cert.NebulaEncryptedData{Ciphertext: ct}\nb, _ := proto.Marshal(ned) // EncryptionMetadata missing\n// after\nned := &cert.NebulaEncryptedData{EncryptionMetadata: meta, Ciphertext: ct}\nb, _ := proto.Marshal(ned)","handlingStrategy":"type-guard","validationCode":"var rned cert.RawNebulaEncryptedData\nif err := proto.Unmarshal(b, &rned); err != nil { return err }\nif rned.EncryptionMetadata == nil { return fmt.Errorf(\"EncryptionMetadata missing\") }","typeGuard":"func hasEncryptionMetadata(b []byte) bool {\n    var r cert.RawNebulaEncryptedData\n    if proto.Unmarshal(b, &r) != nil { return false }\n    return r.EncryptionMetadata != nil\n}","tryCatchPattern":"ned, err := cert.UnmarshalNebulaEncryptedData(b)\nif err != nil {\n    if strings.Contains(err.Error(), \"EncryptionMetadata was nil\") { /* malformed blob - re-encrypt */ }\n    return err\n}","preventionTips":["Always use EncryptAndMarshal* helpers to produce blobs; never hand-assemble the protobuf","Confirm the blob is a NebulaEncryptedData message, not another type","Re-encrypt data produced by incomplete or older external tooling"],"tags":["crypto","protobuf","missing-field","metadata"],"backgroundTag":"missing-required-argument","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"}