{"record":{"id":"e0cfaa4f5340a386","repo":"netbirdio/netbird","slug":"invalid-protocol-w-e0cfaa","errorCode":null,"errorMessage":"invalid protocol: %w","messagePattern":"invalid protocol: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/internal/acl/manager.go","lineNumber":260,"sourceCode":"\t}\n\n\tvar sources []netip.Prefix\n\tfor _, sourceRange := range rule.SourceRanges {\n\t\tsource, err := netip.ParsePrefix(sourceRange)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"parse source range: %w\", err)\n\t\t}\n\t\tsources = append(sources, source)\n\t}\n\n\tdestination, err := determineDestination(rule, dynamicResolver, sources)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"determine destination: %w\", err)\n\t}\n\n\tprotocol, err := convertToFirewallProtocol(rule.Protocol)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid protocol: %w\", err)\n\t}\n\n\taction, err := convertFirewallAction(rule.Action)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid action: %w\", err)\n\t}\n\n\tdPorts := convertPortInfo(rule.PortInfo)\n\n\taddedRule, err := d.firewall.AddRouteFiltering(rule.PolicyID, sources, destination, protocol, nil, dPorts, action)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"add route rule: %w\", err)\n\t}\n\n\treturn id.RuleID(addedRule.ID()), nil\n}\n\nfunc (d *DefaultManager) protoRuleToFirewallRule(","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/internal/acl/manager.go#L242-L278","documentation":"Returned by applyRouteACL when convertToFirewallProtocol hits its default branch: the proto RuleProtocol value is outside {TCP, UDP, ICMP, ALL} known to this agent build. Note the function still returns ProtocolALL alongside the error, but the caller discards the rule, and because the ACL default posture is deny, the route's traffic is not permitted by this rule. New enum values are exactly how a newer management breaks an older agent here.","triggerScenarios":"Management newer than the agent emitting a RuleProtocol the old agent's switch does not know; RuleProtocol_UNKNOWN/unset (0) reaching route ACLs from unvalidated API writes; custom management forks adding protocols.","commonSituations":"Partial fleet upgrades: dashboard/management already supports a new protocol, agents lag; scripts creating access policies with an empty/invalid protocol field.","solutions":["Update the agent to at least the version of management in use so the enum coverage matches","Set a concrete protocol (tcp/udp/icmp/all) on the affected network route policy","If rolling updates take time, remove the offending policy for the lagging agents so their route rules apply cleanly"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// whitelist check before dispatching a rule to agents\nvar knownProtocols = map[mgmProto.RuleProtocol]bool{\n    mgmProto.RuleProtocol_TCP: true,\n    mgmProto.RuleProtocol_UDP: true,\n    mgmProto.RuleProtocol_ICMP: true,\n    mgmProto.RuleProtocol_ALL: true,\n}\n\nfunc protocolSupportedByAgents(p mgmProto.RuleProtocol) bool {\n    return knownProtocols[p]\n}","typeGuard":"func isKnownProtocol(p mgmProto.RuleProtocol) bool {\n    switch p {\n    case mgmProto.RuleProtocol_TCP, mgmProto.RuleProtocol_UDP,\n        mgmProto.RuleProtocol_ICMP, mgmProto.RuleProtocol_ALL:\n        return true\n    }\n    return false\n}","tryCatchPattern":"protocol, err := convertToFirewallProtocol(rule.Protocol)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid protocol type\") {\n        log.Warnf(\"management sent unknown protocol %d - agent older than management? rule skipped\", rule.Protocol)\n    }\n    return \"\", fmt.Errorf(\"invalid protocol: %w\", err)\n}","preventionTips":["Upgrade agents before (or together with) management so new protocol enums are understood","Always set an explicit protocol on network route policies; never rely on the zero value","On mixed fleets, avoid new protocol values in policies until the oldest agent supports them"],"tags":["go","netbird","acl","protocol-enum","version-mismatch","policy"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}