grpc/grpc-go · error

trailing data after IssuingDistributionPoint extension

Error message

trailing data after IssuingDistributionPoint extension

What it means

Returned by parseCRLExtensions when asn1.Unmarshal of the IssuingDistributionPoint extension decoded into issuingDistributionPoint but left trailing bytes. The IDP extension must be a single SEQUENCE; leftover bytes mean the encoding is malformed, so the CRL is rejected before use.

Solutions

  1. Re-fetch the CRL from its distribution point.
  2. Verify with openssl crl -inform DER -text -noout that the IDP extension parses cleanly.
  3. If the issuer is consistently non-conformant, request a corrected CRL or remove CRL-based revocation for that chain.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check the IssuingDistributionPoint extension for trailing bytes.
func precheckIDP(crlDER []byte) error {
    l, err := x509.ParseRevocationList(crlDER)
    if err != nil { return err }
    for _, ext := range l.Extensions {
        if ext.Id.Equal(oidIssuingDistributionPoint) {
            var dp issuingDistributionPoint
            rest, err := asn1.Unmarshal(ext.Value, &dp)
            if err != nil { return err }
            if len(rest) != 0 { return errors.New("IDP has trailing bytes") }
        }
    }
    return nil
}

Try / catch

On parse error from CRL loading, log the CRL source, retain the previously known-good CRL, and schedule a retry. Do not silently skip revocation checks.

Prevention

When it happens

Trigger: The CRL's IssuingDistributionPoint extension has trailing bytes after the SEQUENCE (len(rest) != 0). Triggered while parsing extensions of a CRL supplied to the advancedtls CRL verifier.

Common situations: Corrupt CRL file. Non-conformant CA emits extra (unknown) fields inside the IDP extension. CRL transferred in text mode with byte-level corruption.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/6f0c15d2d81afb99. Report an issue: GitHub.

Appendix: source

Thrown at security/advancedtls/crl.go:341

		switch {
		case oidDeltaCRLIndicator.Equal(ext.Id):
			return nil, fmt.Errorf("delta CRLs unsupported")

		case oidAuthorityKeyIdentifier.Equal(ext.Id):
			var a authKeyID
			if rest, err := asn1.Unmarshal(ext.Value, &a); err != nil {
				return nil, fmt.Errorf("asn1.Unmarshal failed: %v", err)
			} else if len(rest) != 0 {
				return nil, errors.New("trailing data after AKID extension")
			}
			certList.authorityKeyID = a.ID

		case oidIssuingDistributionPoint.Equal(ext.Id):
			var dp issuingDistributionPoint
			if rest, err := asn1.Unmarshal(ext.Value, &dp); err != nil {
				return nil, fmt.Errorf("asn1.Unmarshal failed: %v", err)
			} else if len(rest) != 0 {
				return nil, errors.New("trailing data after IssuingDistributionPoint extension")
			}

			if dp.OnlyContainsUserCerts || dp.OnlyContainsCACerts || dp.OnlyContainsAttributeCerts {
				return nil, errors.New("CRL only contains some certificate types")
			}
			if dp.IndirectCRL {
				return nil, errors.New("indirect CRLs unsupported")
			}
			if dp.OnlySomeReasons.BitLength != 0 {
				return nil, errors.New("onlySomeReasons unsupported")
			}

		case ext.Critical:
			return nil, fmt.Errorf("unsupported critical extension: %v", ext.Id)
		}
	}

	if len(certList.authorityKeyID) == 0 {

View on GitHub (pinned to 0c51461d27)