slackhq/nebula · error
ErrBadFormat
ErrBadFormat
Error message
bad wire format
What it means
ErrBadFormat signals that an input byte slice is not a well-formed Nebula v2 certificate wire format. unmarshalCertificateV2 rejects buffers that are empty, exceed MaxCertificateSize, or whose ASN.1 DER envelope cannot be parsed as the expected SEQUENCE structure.
Solutions
- Verify the bytes are the raw DER payload of a v2 certificate, not the PEM text — decode the PEM block first (pem.Decode) and pass block.Bytes.
- Check len(b) > 0 and len(b) <= MaxCertificateSize before calling.
- Confirm the peer / file is actually serving a Nebula v2 certificate; v1 certs must be decoded with the v1 unmarshal path.
- Inspect the source of the bytes for truncation or corruption (log the length and first bytes).
Example fix
// before
raw, _ := os.ReadFile("ca.crt")
c, err := cert.UnmarshalCertificateV2(raw)
// after
block, _ := pem.Decode(raw)
c, err := cert.UnmarshalCertificateV2(block.Bytes)
if err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
if len(b) == 0 || len(b) > cert.MaxCertificateSize {
return fmt.Errorf("cert payload: got %d bytes", len(b))
} Type guard
func isPlausibleCertBytes(b []byte) bool {
return len(b) > 0 && len(b) <= cert.MaxCertificateSize && b[0] == 0x30 // DER SEQUENCE
} Try / catch
c, err := cert.UnmarshalCertificateV2(b)
if errors.Is(err, cert.ErrBadFormat) {
return fmt.Errorf("not a v2 nebula certificate (%d bytes); check PEM decoding", len(b))
} Prevention
- Always pem.Decode before unmarshaling cert files.
- Check byte length against cert.MaxCertificateSize first.
- Confirm certificate version (v1 vs v2) and use the matching unmarshal API.
When it happens
Trigger: Calling unmarshalCertificateV2 / unmarshalDetails with a zero-length byte slice, a byte slice larger than MaxCertificateSize, or bytes whose DER envelope is not an ASN.1 SEQUENCE or has an empty body (cert/cert_v2.go:573-579).
Common situations: Loading a v1 certificate or a PEM-encoded file without stripping the PEM armor before passing raw bytes; truncated network transmission; pointing a config field at a non-certificate file; receiving garbage on the handshake channel.
Related errors
- error while unmarshaling cert
- ErrTruncatedPEMBlock
- appears to be a range but could not be parsed;
- bad cpulist range
- can not sign a CA certificate with another
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/c1b8e6723eff2853.
Report an issue: GitHub.
Appendix: source
Thrown at cert/errors.go:9
package cert
import (
"errors"
"fmt"
)
var (
ErrBadFormat = errors.New("bad wire format")
ErrRootExpired = errors.New("root certificate is expired")
ErrExpired = errors.New("certificate is expired")
ErrNotCA = errors.New("certificate is not a CA")
ErrNotSelfSigned = errors.New("certificate is not self-signed")
ErrBlockListed = errors.New("certificate is in the block list")
ErrFingerprintMismatch = errors.New("certificate fingerprint did not match")
ErrSignatureMismatch = errors.New("certificate signature did not match")
ErrInvalidPublicKey = errors.New("invalid public key")
ErrInvalidPrivateKey = errors.New("invalid private key")
ErrPublicPrivateCurveMismatch = errors.New("public key does not match private key curve")
ErrPublicPrivateKeyMismatch = errors.New("public key and private key are not a pair")
ErrPrivateKeyEncrypted = errors.New("private key must be decrypted")
ErrCaNotFound = errors.New("could not find ca for the certificate")
ErrUnknownVersion = errors.New("certificate version unrecognized")
ErrCertPubkeyPresent = errors.New("certificate has unexpected pubkey present")
ErrCurveMismatch = errors.New("certificate curve does not match CA")
ErrInvalidPEMBlock = errors.New("input did not contain a valid PEM encoded block")View on GitHub (pinned to dd8f660c0a)