{"record":{"id":"8a47129f860e4e2f","repo":"ory/hydra","slug":"failed-to-resolve-s","errorCode":null,"errorMessage":"failed to resolve %s","messagePattern":"failed to resolve (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/ipx/ip_validator.go","lineNumber":79,"sourceCode":"\t\tif !allowed(addr.Addr()) {\n\t\t\treturn errors.Errorf(\"ip %s is not a permitted destination\", addr.Addr())\n\t\t}\n\t\treturn nil\n\t}\n\n\tctx, cancel := context.WithTimeoutCause(ctx, 2*time.Second, errors.New(\"DNS lookup timed out\"))\n\tdefer cancel()\n\tips, err := resolver.LookupNetIP(ctx, \"ip\", ipOrHostname)\n\tif err != nil {\n\t\tif dnsErr, ok := stderrors.AsType[*net.DNSError](err); ok {\n\t\t\t// Copy the `*net.DNSError` before masking `Server` to avoid a data\n\t\t\t// race: the DNS resolver uses `singleflight` to deduplicate\n\t\t\t// concurrent lookups, so multiple goroutines may receive the same\n\t\t\t// `*net.DNSError` pointer. Mutating it in place races with concurrent\n\t\t\t// readers (e.g. the `otelhttp` `dnsDone` trace hook).\n\t\t\tmaskedDNS := *dnsErr\n\t\t\tmaskedDNS.Server = \"\" // Mask our DNS server's IP address.\n\t\t\treturn errors.Wrapf(&maskedDNS, \"failed to resolve %s\", ipOrHostnameOrURL)\n\t\t}\n\t}\n\n\tfor _, ip := range ips {\n\t\tif !allowed(ip) {\n\t\t\treturn errors.Wrapf(&net.DNSError{\n\t\t\t\tErr:         \"no such host\",\n\t\t\t\tName:        ipOrHostname,\n\t\t\t\tServer:      \"\",\n\t\t\t\tIsTimeout:   false,\n\t\t\t\tIsTemporary: false,\n\t\t\t\tIsNotFound:  true,\n\t\t\t}, \"failed to resolve %s\", ipOrHostnameOrURL)\n\t\t}\n\t}\n\n\treturn nil\n}","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/ipx/ip_validator.go#L61-L97","documentation":"Returned by IsAssociatedIPAllowed when the DNS lookup of the given hostname (with a 2-second timeout) fails. The hostname could not be resolved to any IP within the deadline, so its addresses cannot be checked against the allow/deny list; the error wraps the underlying net.DNSError with the hostname included.","triggerScenarios":"Thrown at oryx/ipx/ip_validator.go:79 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Distinguish net.DNSError: isTemporary/notFound failures may warrant a retry","Verify the hostname is spelled correctly and resolvable by the host's resolver","Treat resolution failure as denial (fail closed) when the SSRF guard must be strict"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}