{"record":{"id":"e90e0ae70b7b52bb","repo":"owasp-amass/amass","slug":"libpostal-is-not-available","errorCode":null,"errorMessage":"libpostal is not available","messagePattern":"libpostal is not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"engine/plugins/support/location.go","lineNumber":119,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\n\t// attempt to convert the province to its two-letter abbreviation\n\tif loc.Country != \"\" && len(loc.Province) > 2 {\n\t\tif c := pioz.Get(loc.Country); c != nil {\n\t\t\tif sub := c.SubdivisionByName(loc.Province); sub.Type != \"\" {\n\t\t\t\tloc.Province = sub.Code\n\t\t\t}\n\t\t}\n\t}\n\n\treturn loc\n}\n\nfunc postalServerParseAddress(address string) ([]parsedComponent, error) {\n\tif !isPostalServerAvailable() {\n\t\treturn nil, errors.New(\"libpostal is not available\")\n\t}\n\n\treqJSON, err := json.Marshal(parseRequest{Address: address})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)\n\tdefer cancel()\n\n\tresp, err := amasshttp.RequestWebPage(ctx, amasshttp.DefaultClient, &amasshttp.Request{\n\t\tMethod: \"POST\",\n\t\tURL:    \"http://\" + postalHost + \":\" + postalPort + \"/parse\",\n\t\tBody:   string(reqJSON),\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/plugins/support/location.go#L101-L137","documentation":"Thrown by postalServerParseAddress when isPostalServerAvailable() reports that the local libpostal REST server is not reachable. Address parsing is delegated to an external libpostal service; without it, StreetAddressToLocation cannot produce Location assets. This is an optional external-dependency availability error.","triggerScenarios":"StreetAddressToLocation is called with an address, and the libpostal parse server is not running or not listening on the expected port, so isPostalServerAvailable() returns false before any HTTP request is made.","commonSituations":"libpostal service not installed or not started (e.g. docker container for nlpodyssey/libpostal not running); wrong REST address/port configuration; server crashed or still starting when the scan ran.","solutions":["Start the libpostal REST server (e.g. docker run -p 8080:8080 openresty/libpostal-rest or equivalent) before the scan","Verify the configured postal server address/port matches the running service","Add a startup health check that waits for the postal server before address parsing","Skip address-to-location enrichment gracefully when libpostal is unavailable"],"exampleFix":"// before\nloc, err := support.StreetAddressToLocation(session, addr)\nif err != nil {\n\treturn err\n}\n// after\nloc, err := support.StreetAddressToLocation(session, addr)\nif err != nil {\n\t// libpostal unavailable; continue without location enrichment\n\treturn nil\n}","handlingStrategy":"fallback","validationCode":"resp, err := http.Get(fmt.Sprintf(\"http://%s:%d/\", postalHost, postalPort))\nif err != nil {\n\t// libpostal unavailable; skip address parsing\n}","typeGuard":"null","tryCatchPattern":"loc, err := support.StreetAddressToLocation(session, addr)\nif err != nil {\n\tif strings.Contains(err.Error(), \"libpostal is not available\") {\n\t\t// fall back: keep the raw address without location enrichment\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Start the libpostal REST server before running address enrichment","Verify server address/port configuration matches the running instance","Add a health check/wait loop at scan startup","Treat location enrichment as optional and degrade gracefully"],"tags":["go","libpostal","optional-dependency","geolocation"],"backgroundTag":"missing-optional-dependency","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}