slackhq/nebula · error

nil byte array

Error message

nil byte array

What it means

UnmarshalNebulaEncryptedData requires a non-empty protobuf-encoded RawNebulaEncryptedData blob. An empty (len 0) input cannot be a valid encrypted-data message, so it is rejected up front with 'nil byte array' instead of letting proto.Unmarshal produce a vaguer error.

Source

Thrown at cert/crypto.go:197

	if err != nil {
		return nil, err
	}

	switch curve {
	case Curve_CURVE25519:
		return pem.EncodeToMemory(&pem.Block{Type: EncryptedEd25519PrivateKeyBanner, Bytes: b}), nil
	case Curve_P256:
		return pem.EncodeToMemory(&pem.Block{Type: EncryptedECDSAP256PrivateKeyBanner, Bytes: b}), nil
	default:
		return nil, fmt.Errorf("invalid curve: %v", curve)
	}
}

// UnmarshalNebulaEncryptedData will unmarshal a protobuf byte representation of a nebula cert into its
// protobuf-generated struct.
func UnmarshalNebulaEncryptedData(b []byte) (*NebulaEncryptedData, error) {
	if len(b) == 0 {
		return nil, fmt.Errorf("nil byte array")
	}
	var rned RawNebulaEncryptedData
	err := proto.Unmarshal(b, &rned)
	if err != nil {
		return nil, err
	}

	if rned.EncryptionMetadata == nil {
		return nil, fmt.Errorf("encoded EncryptionMetadata was nil")
	}

	if rned.EncryptionMetadata.Argon2Parameters == nil {
		return nil, fmt.Errorf("encoded Argon2Parameters was nil")
	}

	params, err := unmarshalArgon2Parameters(rned.EncryptionMetadata.Argon2Parameters)
	if err != nil {
		return nil, err

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Check the input source: ensure the PEM block decoded successfully and block.Bytes is non-empty before calling
  2. Propagate/handle earlier errors - an upstream read that failed likely returned nil, causing this downstream error
  3. Regenerate the encrypted key file if the source file itself is empty

Example fix

// before
block, _ := pem.Decode(raw)
data, err := cert.UnmarshalNebulaEncryptedData(block.Bytes) // block may be nil
// after
block, _ := pem.Decode(raw)
if block == nil || len(block.Bytes) == 0 {
    return fmt.Errorf("no encrypted nebula data found")
}
data, err := cert.UnmarshalNebulaEncryptedData(block.Bytes)
Defensive patterns

Strategy: validation

Validate before calling

if len(b) == 0 { return fmt.Errorf("no encrypted data to unmarshal") }

Type guard

func hasEncryptedData(b []byte) bool { return len(b) > 0 }

Try / catch

ned, err := cert.UnmarshalNebulaEncryptedData(b)
if err != nil {
    if strings.Contains(err.Error(), "nil byte array") { /* upstream read failed */ }
    return err
}

Prevention

When it happens

Trigger: Calling UnmarshalNebulaEncryptedData(nil) or UnmarshalNebulaEncryptedData([]byte{}) - typically when a PEM block decoded to nothing, a file was empty, or an upstream function returned a nil byte slice on error and its error was ignored.

Common situations: Reading an empty or zero-length key file; pem.Decode returning nil and dereferencing block.Bytes unguarded; a caller swallowing an earlier error and forwarding nil bytes to decryption.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/6ae89b95ece743b9. Report an issue: GitHub.