{"record":{"id":"12e96c55c11a219a","repo":"ipfs/kubo","slug":"invalid-bootstrap-address-s","errorCode":null,"errorMessage":"invalid bootstrap address: %s","messagePattern":"invalid bootstrap address: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/bootstrap.go","lineNumber":281,"sourceCode":"\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc bootstrapAdd(r repo.Repo, cfg *config.Config, peers []string) ([]string, error) {\n\t// Validate peers - skip validation for \"auto\" placeholder\n\tfor _, p := range peers {\n\t\tif p == config.AutoPlaceholder {\n\t\t\tcontinue // Skip validation for \"auto\" placeholder\n\t\t}\n\t\tm, err := ma.NewMultiaddr(p)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttpt, p2ppart := ma.SplitLast(m)\n\t\tif p2ppart == nil || p2ppart.Protocol().Code != ma.P_P2P {\n\t\t\treturn nil, fmt.Errorf(\"invalid bootstrap address: %s\", p)\n\t\t}\n\t\tif tpt == nil {\n\t\t\treturn nil, fmt.Errorf(\"bootstrap address without a transport: %s\", p)\n\t\t}\n\t}\n\n\taddedMap := map[string]struct{}{}\n\taddedList := make([]string, 0, len(peers))\n\n\t// re-add cfg bootstrap peers to rm dupes\n\tbpeers := cfg.Bootstrap\n\tcfg.Bootstrap = nil\n\n\t// add new peers\n\tfor _, s := range peers {\n\t\tif _, found := addedMap[s]; found {\n\t\t\tcontinue\n\t\t}","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/bootstrap.go#L263-L299","documentation":"`bootstrapAdd` validates each peer string as a multiaddr whose last component is the `/p2p/<peerID>` protocol. `ma.SplitLast(m)` returns the transport part and the p2p part; if the p2p part is missing or is not P_P2P, the address is rejected with `invalid bootstrap address: %s`. The string parsed as a multiaddr but does not identify a peer.","triggerScenarios":"`ipfs bootstrap add` with an address lacking a `/p2p/<peerID>` suffix, e.g. `/ip4/1.2.3.4/tcp/4001`, a malformed peer ID after /p2p/, or a bare peer ID string.","commonSituations":"Copying transport-only addresses from server configs; truncated multiaddrs in shell scripts; misspelled legacy `/ipfs/` suffix; DNS addresses missing the peer ID component.","solutions":["Append the peer ID: `/ip4/1.2.3.4/tcp/4001/p2p/<peerID>` (or `/dnsaddr/.../p2p/<peerID>`)","Get the full address from the remote node with `ipfs id` (Addresses field)","Validate locally with ma.NewMultiaddr + SplitLast before scripting the add"],"exampleFix":"// before\nipfs bootstrap add /ip4/104.131.131.82/tcp/4001\n// after\nipfs bootstrap add /ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ","handlingStrategy":"validation","validationCode":"func validBootstrapAddr(p string) bool {\n    m, err := ma.NewMultiaddr(p)\n    if err != nil { return false }\n    _, last := ma.SplitLast(m)\n    return last != nil && last.Protocol().Code == ma.P_P2P\n}","typeGuard":"null","tryCatchPattern":"if err != nil && strings.HasPrefix(err.Error(), \"invalid bootstrap address:\") {\n    // fix the multiaddr: append /p2p/<peerID>\n}","preventionTips":["Always append /p2p/<peerID> to transport multiaddrs","Copy addresses from `ipfs id` output, not hand-typed","Validate with a multiaddr parser before scripting adds","Beware truncated addresses in shell variables/wrapping"],"tags":["cli","bootstrap","multiaddr","validation"],"backgroundTag":"invalid-multiaddr","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}