{"record":{"id":"e50e00132162aab9","repo":"appsmithorg/appsmith","slug":"host-host-is-not-allowed","errorCode":null,"errorMessage":"Host {host} is not allowed","messagePattern":"Host (.+?) is not allowed","errorType":"exception","errorClass":"UnknownHostException","httpStatus":null,"severity":"error","filePath":"app/server/appsmith-plugins/elasticSearchPlugin/src/main/java/org/apache/http/impl/nio/client/HttpAsyncClientBuilder.java","lineNumber":658,"sourceCode":"     */\n    public final HttpAsyncClientBuilder useSystemProperties() {\n        systemProperties = true;\n        return this;\n    }\n\n    private static String[] split(final String s) {\n        if (TextUtils.isBlank(s)) {\n            return null;\n        }\n        return s.split(\" *, *\");\n    }\n\n    public CloseableHttpAsyncClient build() {\n        // This `dnsResolver` is the only thing different from the original class.\n        // In the original class, it is set to SystemDefaultDnsResolver.INSTANCE, inlined.\n        final DnsResolver dnsResolver = host -> {\n            if (RestrictedHostFilter.isDisallowedAndFail(host, null)) {\n                throw new UnknownHostException(\"Host \" + host + \" is not allowed\");\n            }\n            final InetAddress[] addresses = InetAddress.getAllByName(host);\n            for (InetAddress address : addresses) {\n                if (RestrictedHostFilter.isDisallowedAndFail(address.getHostAddress(), null)) {\n                    throw new UnknownHostException(\"Host \" + host + \" is not allowed\");\n                }\n            }\n            return addresses;\n        };\n\n        PublicSuffixMatcher publicSuffixMatcher = this.publicSuffixMatcher;\n        if (publicSuffixMatcher == null) {\n            publicSuffixMatcher = PublicSuffixMatcherLoader.getDefault();\n        }\n\n        NHttpClientConnectionManager connManager = this.connManager;\n        if (connManager == null) {\n            SchemeIOSessionStrategy sslStrategy = this.sslStrategy;","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/appsmithorg/appsmith/blob/8cd9021c24cdbea1c3c12c966073708e83db60c2/app/server/appsmith-plugins/elasticSearchPlugin/src/main/java/org/apache/http/impl/nio/client/HttpAsyncClientBuilder.java#L640-L676","documentation":"The ElasticSearch plugin overrides Apache HttpAsyncClient's DnsResolver to enforce SSRF protection via RestrictedHostFilter. Before any DNS lookup, the hostname literal is checked against a blocklist: disallowed hostnames, blocked IP address classes (loopback, link-local 169.254/16, multicast, any-local 0.0.0.0, IPv6 Unique-Local fc00::/7), and the Appsmith instance's own hostnames/IPs. If the literal is disallowed, an UnknownHostException is thrown.","triggerScenarios":"The ElasticSearch datasource host is (or canonicalizes to) a loopback address like 127.0.0.1 or localhost, a link-local address like 169.254.169.254 (AWS metadata), an any-local address, an IPv6 ULA, or the Appsmith instance's own hostname or IP.","commonSituations":"Pointing ElasticSearch at localhost or 127.0.0.1 for local development; using the instance's internal hostname; attempting to reach the cloud metadata endpoint; using a link-local address in a containerized environment.","solutions":["Use the external, routable hostname or IP of the ElasticSearch cluster.","If running locally in Docker, use the host's LAN IP or a Docker service name resolvable from the container, not localhost.","Ensure the host is not in a blocked address class — loopback, link-local, multicast, and ULA are always blocked.","If a legitimately internal cluster must be reached, consult Appsmith's network allow-list configuration or deploy behind a trusted network boundary."],"exampleFix":"// before — loopback blocked by SSRF filter\ndsConfig.setUrl(\"http://localhost:9200\");\n\n// after — routable address\ndsConfig.setUrl(\"http://10.0.0.5:9200\"); // or the cluster's public IP/host","handlingStrategy":"validation","validationCode":"import com.appsmith.util.RestrictedHostFilter;\n\nURI uri = URI.create(dsConfig.getUrl());\nString host = uri.getHost();\nif (RestrictedHostFilter.isDisallowedAndFail(host, null)) {\n    throw new IllegalArgumentException(\n        \"Host '\" + host + \"' is blocked by SSRF protection. Use a routable address.\");\n}","typeGuard":null,"tryCatchPattern":"// Catch UnknownHostException from the ElasticSearch client build/connect:\ntry {\n    client.execute(request);\n} catch (UnknownHostException e) {\n    if (e.getMessage().contains(\"is not allowed\")) {\n        log.warn(\"SSRF filter blocked host: {}\", e.getMessage());\n        return errorResult(\"Host is not allowed by SSRF protection.\");\n    }\n    throw e;\n}","preventionTips":["Use external, routable hostnames or IPs for ElasticSearch datasources.","Never point datasources at localhost, 127.0.0.1, or 169.254.169.254.","In Docker, use the host LAN IP or a resolvable service name, not localhost.","Run RestrictedHostFilter.isDisallowedAndFail on the host before configuring the datasource."],"tags":["elasticsearch","ssrf","host-filter","dns","security"],"backgroundTag":null,"analyzedSha":"8cd9021c24cdbea1c3c12c966073708e83db60c2","analyzedAt":"2026-08-12T22:14:19.293Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}