cilium/cilium · error

failed to decode base64-encoded NLRI: %w

Error message

failed to decode base64-encoded NLRI: %w

What it means

ToAgentPath converts an API BgpPath model back into an internal table.Path. The NLRI arrives as a base64 string, and this error means base64.StdEncoding.DecodeString failed — the string is not valid standard base64 (bad characters, wrong padding, or it was produced by a different encoder such as URL-safe base64). No BGP parsing has happened yet.

Source

Thrown at pkg/bgp/api/conversions.go:130

			Base64: base64.StdEncoding.EncodeToString(bin),
		})
	}

	return ret, nil
}

func ToAgentPath(m *models.BgpPath) (*types.Path, error) {
	p := &types.Path{}

	if m.AgeNanoseconds > 0 {
		p.CreatedAt = time.Now().Add(-time.Duration(m.AgeNanoseconds))
	}
	p.Best = m.Best

	// Decode serialized NLRI to bytes
	bin, err := base64.StdEncoding.DecodeString(m.Nlri.Base64)
	if err != nil {
		return nil, fmt.Errorf("failed to decode base64-encoded NLRI: %w", err)
	}

	// Decode NLRI from bytes
	afi := types.ParseAfi(m.Family.Afi)
	safi := types.ParseSafi(m.Family.Safi)
	nlri, err := bgp.NLRIFromSlice(bgp.NewFamily(uint16(afi), uint8(safi)), bin)
	if err != nil {
		return nil, fmt.Errorf("failed to decode NLRI: %w", err)
	}

	p.NLRI = nlri
	p.Family = types.Family{Afi: afi, Safi: safi}

	// Decode path attributes
	for _, pattr := range m.PathAttributes {
		bin, err := base64.StdEncoding.DecodeString(pattr.Base64)
		if err != nil {
			return nil, fmt.Errorf("failed to decode base64-encoded Path Attribute: %w", err)

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Re-obtain the base64 string directly from the GoBGP API (e.g. via ToAPIPath output or gRPC response) instead of manual copying
  2. Strip whitespace/newlines and restore '=' padding before decoding
  3. If the string came from a non-Go encoder, re-encode with standard base64 (StdEncoding)
  4. Sanitize with strings.NewReplacer and pad to a multiple of 4 in a preprocessing step

Example fix

// before
m.Nlri.Base64 = "EAAKAgCjAAEA" + "\n" // newline from log copy
p, err := api.ToAgentPath(m) // fails
// after
m.Nlri.Base64 = strings.TrimSpace("EAAKAgCjAAEA")
p, err := api.ToAgentPath(m)
Defensive patterns

Strategy: validation

Validate before calling

func validBase64(s string) bool {
    _, err := base64.StdEncoding.DecodeString(s)
    return err == nil && s != ""
}
// if !validBase64(m.Nlri.Base64) { regenerate or reject }

Type guard

func hasDecodableNLRI(m *models.BgpPath) bool {
    return m.Nlri != nil && validBase64(m.Nlri.Base64)
}

Try / catch

p, err := api.ToAgentPath(m)
if err != nil {
    return nil, fmt.Errorf("nlri base64 invalid (len=%d): %w", len(m.Nlri.Base64), err)
}

Prevention

When it happens

Trigger: Calling ToAgentPath/ToAgentPaths with a models.BgpPath whose Nlri.Base64 was hand-written, truncated, contains whitespace/newlines, or was encoded with base64.URLEncoding or RawStdEncoding instead of StdEncoding.

Common situations: Copy-pasting NLRI strings from logs where line-wrapping inserted characters; storing paths in a text store that mangled padding '='; a client (e.g. from another language) using URL-safe base64.

Understand the failure class

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/c533655b1db3c214. Report an issue: GitHub.