...

Configuring the NGINX Resolver Cache Correctly

The NGINX Resolver Cached DNS responses for backend names, but not HTTP responses. For a robust reverse proxy configuration, use a trusted internal nameserver, generally allow well-maintained DNS TTLs to take effect, and set valid only as a deliberate override. The resolver becomes particularly important when dealing with variable targets in proxy_pass as well as for dynamic upstreams, whose functionality depends on the installed version of NGINX.

Understanding the NGINX Resolver and DNS Cache

A reverse proxy first needs an IP address for a backend with a hostname. The NGINX Resolver It queries the name servers specified in the configuration. The DNS response is cached so that NGINX does not have to resolve the name again for every request during its validity period. This cache applies exclusively to name resolution for the target system.

The Directive resolver contains one or more resolver addresses or supported resolver identifiers. Unless a different port is specified, NGINX uses port 53; if multiple servers are listed, requests are routed using the round-robin method, according to the documentation. For a robust bootstrap configuration, static IP addresses are often preferable because their resolution does not depend on DNS itself.

By default, NGINX takes into account both IPv4 and IPv6 addresses associated with a name. This is appropriate if the network reliably transmits both protocol families all the way to the backend. Parameters such as ipv4=off or ipv6=off They specifically exclude a family, but they are not a general cache optimization. Whether they are necessary depends on the accessibility of the specific backend, not on the mere existence of an AAAA record.

The resolver is neither a full-fledged recursive DNS server nor does it automatically adopt all settings from /etc/resolv.conf. NGINX uses the explicitly specified name servers. For internal zones and production backend names, these should be trusted, appropriately secured resolvers within your own network. This ensures that responsibility for private names and protection against manipulated DNS responses remain within a controllable infrastructure.

A DNS cache is not an HTTP cache

The resolver's DNS response cache stores mappings between names and DNS responses, such as A or AAAA addresses. Its purpose is to enable the resolver to reach a backend again without having to repeat the name resolution process each time. Therefore, if a backend IP address changes, the validity of the DNS response is what matters—not the content of a previously delivered HTTP response.

Separately, it stores proxy_cache HTTP responses from an upstream server. Depending on the configuration, the key may include, for example, the URI, host, or header; a match returns a previously cached response to the client. Problems here can manifest as outdated pages, incorrect variants, or unexpected cache hits. This function does not determine which IP address NGINX uses when establishing a new backend connection.

The open-file cache is a third-level cache: It stores file information and open descriptors for local file system accesses, but neither DNS responses nor HTTP content. Anyone who wants to learn more about this distinction in the context of static delivery can find it in the article on Configuring the NGINX Open File Cache. However, it does not provide a basis for deciding on a resolver TTL.

Flushing, purging, or resetting an HTTP cache therefore does not speed up a DNS change. Conversely, a new DNS resolution does not correct an incorrectly cached HTTP response. With a reverse proxy, the DNS Cache It also relies on names and addresses: It neither checks the health of an application nor does it replace load balancing, retries, or proper timeout planning for the upstream.

When NGINX Needs to Resolve Names Again

NGINX may already know a hostname when it reads the configuration. The situation is different for a variable target, such as proxy_pass http://$backend;. NGINX first searches for the resulting name in defined upstream groups. If it does not find a matching name there, it requires a configured resolver at runtime to determine the destination address.

The message no resolver defined In this context, it does not indicate a missing HTTP cache. It means that NGINX does not know of a DNS server to perform the necessary runtime resolution. resolver may be used in the context of http, server or location are listed. A key entry in the http-Block is appropriate when multiple virtual hosts use the same resolver; a narrower scope is only suitable if the requirements actually differ.

This runtime resolution, which has been available for a long time, should be distinguished from the dynamic updating of a classic upstream group. The resolver configuration directly in the upstream-block and server hostname resolve According to the NGINX documentation, these features are available in the open-source version starting with version 1.27.3. Older open-source installations should not be assumed to support this pattern automatically; historically, some of these features were reserved for NGINX Plus.

Before planning dynamic upstreams, check the installed output and build information. The following command displays the NGINX version, the compiler version, and the `configure` parameters used during the build.

Code
nginx -V

For critical deployments, compare the displayed status with the documentation for the specific package being used and its provider. The key factor is whether this installation documents and provides the required functionality. Only then is a dynamic upstream A robust architectural decision.

Explicitly set TTL and valid

Without any additional configuration, the NGINX resolver cache follows the DNS-TTL in the response from the queried nameserver. If the authoritative DNS operator changes the IP address of a backend, NGINX uses the previous response until its TTL expires. Only when name resolution is required again afterward does NGINX query the resolver once more. This ensures that the validity period remains controllable at the point where the name data is maintained.

The parameter valid completely replaces this TTL with the configured time period. In other words, it does not set an upper limit on the DNS TTL, nor does it define a regular refresh in addition to the TTL. A value of valid=30s It can shorten a longer DNS TTL, but it can also extend a TTL that was intentionally set to be short. This must align with the backend's migration and deployment plans.

Illustration showing the effect of DNS-TTL and "valid" on the cache duration in the NGINX resolver.
DNS TTL and a "valid" override determine, in different ways, how long responses are used.

If the zone is maintained reliably, a configuration without an override is the appropriate starting point. The address in the example is selected based on the networks described in the documentation and must not be used as a production resolver. Instead, enter the address of an accessible and trusted DNS resolver from your own network.

Code
resolver 192.0.2.53;
resolver_timeout 5s;

An override may be useful if the DNS TTL cannot be adjusted and there is a documented operational policy. In that case, the override explicitly shows how long NGINX caches responses. It is not a general performance optimization: Shorter times can trigger more DNS queries, while longer times can delay the switch to new backend addresses.

Code
resolver 192.0.2.53 valid=30s;
resolver_timeout 5s;
Initial decisions for DNS TTL and valid
Operational SituationInitial DecisionReasonRisk
DNS zone with properly maintained TTLsOmit "valid"NGINX follows the cache duration specified by the DNS.The TTL must match the modification window.
TTL cannot be controlled; changes are rareDocument "valid" explicitlyThe holding period for the proxy can now be planned.Old destination addresses can be used for longer than intended by the DNS.
Frequent service or container changesPrefer short TTLs in authoritative DNSThe DNS remains the primary source for up-to-date information.More queries can put a strain on the resolver infrastructure.
DNS-Based Service DiscoveryCheck Dynamic Upstream with resolveUpstream members can track DNS changes.The version and architecture must support the feature.

The decision therefore does not begin with a specific number of seconds, but rather with the question of who controls DNS data and how quickly a backend change must take effect. valid is a deliberate modification to this rule. It is not suitable as a blanket solution to speed up the reverse proxy or to mask DNS issues.

Resolving variables correctly in `proxy_pass`

Contains proxy_pass If the hostname is a variable, NGINX must process the resulting hostname at runtime. First, NGINX searches for a matching upstream group; if it does not find one, it requires a configured resolver for the name. If one is missing, the typical message is no resolver defined This is not a reference to an HTTP cache, but rather to the missing DNS configuration for this execution path.

The following example deliberately highlights the runtime resolution. The resolver is located in the http-context and therefore applies to multiple virtual hosts, unless a more specific setting overrides it. The documentation address used must be replaced by the internal resolver of the respective environment.

Code
http {
    resolver 192.0.2.53;
    resolver_timeout 5s;

    server {
        listen 80;

        location / {
            set $backend api.internal.example;
            proxy_pass http://$backend;
        }
    }
}

The Directive resolver_timeout does not control the cache duration. It limits how long NGINX waits for a name resolution; the documented default is 30 seconds. The choice falls under the category of error budgets: A value that is too high can delay a failed request until an error response is returned, while a value that is too low can cause avoidable resolution errors when internal resolvers are temporarily slow.

For a single, clearly defined location, the resolver can be used in the location-block. If multiple locations or servers require the same resolution, a common scope in the server- or http-Block requires less maintenance. NGINX allows this directive in all three contexts; its scope should reflect the actual operational structure, not just serve to temporarily resolve a single error message.

Even with variable targets, DNS timeouts and connections to the backend remain separate error categories. Successful name resolution does not prove that the target port is reachable or that the application is responding. Conversely, a longer upstream timeout does not resolve an unreachable resolver address.

Configuring Dynamic Upstreams with `resolve`

For a named backend group, a dynamic upstream may be more readable than a variable target value in each location. This pattern separates the definition of backend members from the routing: proxy_pass refers to the group, while the hostname in the upstream can be updated via DNS. This is particularly useful when multiple routes point to the same application.

The parameter resolve for a server-This entry has existed since NGINX 1.5.12. However, according to the documentation, it is only available in the NGINX Open Source version starting with 1.27.3; prior to that, this feature was commercially restricted. The resolver configuration directly in the upstream-Block is documented for open source starting with version 1.27.3.

The Shared Memory Zone It is neither a cache timeout nor a DNS data path. It provides shared memory within NGINX that is required for dynamically changing upstream configurations. If NGINX resolves the DNS and finds other addresses for the name, the upstream group can be adjusted based on this internally managed state without a restart.

Conceptual diagram of a dynamic NGINX upstream with a separate DNS resolver, internal shared-memory state, and backend addresses.
The shared-memory zone manages upstream state within NGINX; DNS resolution and backend connections remain separate.
Code
http {
    resolver 192.0.2.53;
    resolver_timeout 5s;

    upstream application_pool {
        zone application_pool 64k;
        server app.internal.example resolve;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://application_pool;
        }
    }
}

As with all examples, 192.0.2.53 only for a documentation address. In practice, the registered resolver must reliably recognize internal names, be accessible from the NGINX network, and be considered trustworthy. Before implementing the changes, you should also verify the actual functionality of the installed package rather than deriving the configuration solely from a current example.

A service that is accessible exclusively via IPv4 may justify a targeted restriction: resolver 192.0.2.53 ipv6=off; Prevents AAAA queries and the selection of an IPv6 address for this resolver context. However, this is a network architecture decision. If dual-stack is functioning properly, IPv6 should not be disabled simply out of habit; by default, NGINX resolves both IP families.

Carefully Verify the Configuration and Roll It Out

Before making a change, first check where the resolver directives actually apply. To do this, locate the active configuration—including any included files—and determine whether the resolver applies to the entire http-context, intended only for a single virtual host or a single path. A scope that is too narrow may prevent another variable proxy path from finding a resolver; conversely, a scope that is too broad makes it difficult to track changes later on.

Each adjustment is followed by the Syntax Check. It reads the configuration and also attempts to open referenced files. This allows you to detect typos, invalid directives, and problems in include files before reloading. However, the check does not verify that the specified DNS server is reachable, knows the expected name, or that the backend behind a resolved address accepts connections.

Code
nginx -t
nginx -s reload

Do not perform the reload until the check has been successfully completed. nginx -s reload This causes NGINX to start new workers with the new configuration and to gracefully terminate old workers. Depending on the installed package and operating system, the service manager provided by that system may trigger the reload instead. To do this, follow the documented installation procedure rather than using commands from an external environment.

Next, schedule a technical review during the designated change window. Compare the expected DNS TTL with the time at which a new backend address is to be used, and verify the service’s reachability via the actually permitted IP family. Also document the resolver address, the selected scope, and any valid-Override. This makes it possible to determine, in the event of a malfunction, whether the cause is DNS, routing, or the application.

Systematically Narrowing Down Typical Resolver Errors

Start troubleshooting the target expression in proxy_pass. If it contains a variable, NGINX must resolve the hostname it contains at runtime, unless that hostname belongs to a defined upstream group. The message no resolver defined therefore first points to a missing element or one that is not visible in the relevant context Resolver Configuration . Add a trusted nameserver in the appropriate context instead of hastily replacing the hostname with a static IP address.

If a resolver is configured, the next step is to check its address, network path, and authority for the zone in use. A public resolver cannot know internal names; an unreachable resolver, on the other hand, causes resolution timeouts. Also check whether the directive is overridden by a more specific setting. NGINX uses only the explicitly specified name servers; it does not automatically use all settings from /etc/resolv.conf.

If an old destination address remains active after a DNS change, check the response TTL and whether a valid. A long override replaces the TTL of the DNS response and can delay the propagation of a change accordingly. The permissible correction is not a blanket rule of the shortest possible duration, but rather a value that is appropriate for the change window and the resilience of the DNS infrastructure; often, omitting valid the cleaner solution.

If you experience connection problems after successfully resolving the address, disconnect DNS from the backend connection. Check whether A and AAAA responses are available and whether the destination is actually routed and reachable via IPv6. ipv6=off is only suitable for an architecture that is verifiably IPv4-only. A DNS timeout affects name resolution; a connection error to an already known IP address, on the other hand, points to a problem with routing, a firewall, a port, or an application.

For dynamic upstreams, the version, shared-memory zone, and resolve are compatible. The documented open-source support for this applies starting with NGINX 1.27.3; older installations should not be treated as equivalent. status_zone Furthermore, API-based resolver statistics are not a general monitoring solution for NGINX Open Source, as the features mentioned pertain to commercial use cases.

Select a resolver strategy for operation

The right strategy doesn't start with a blanket cache value, but with DNS control and the rate of change. If your team can maintain the authoritative zone and if its TTLs realistically reflect the deployment window, then a TTL-Controlled Resolution without valid is usually the most logical starting point. DNS then remains the authoritative source for determining how long a response is used.

A deliberately placed valid This is an option if you can't control the TTL and can justify a different cache duration for operational reasons. Be sure to determine what level of downtime is acceptable: A longer value reduces the number of potential DNS queries, but may point to an address that is no longer valid after a move. It is neither an upper limit for the DNS TTL nor a general performance toggle.

Select the NGINX pattern based on the routing structure. A variable proxy_pass is suitable when the destination is determined at runtime for each request or configuration; this requires a resolver in the appropriate scope. For a named backend group with DNS-based address changes, an upstream with zone and resolve That's clear, provided that NGINX Open Source 1.27.3 or later is actually available.

Only then do you decide Timeouts and IP Families. The resolver timeout must match the client and upstream timeouts so that a lack of a DNS response does not cause disproportionate delays. Enable IPv4 or IPv6 only as appropriate for your network architecture. Use only secure resolvers that can reliably respond to internal zones.

DNS resolution and upstream keepalive serve different purposes. The resolver determines which backend address NGINX can use; keepalive maintains already established, inactive backend connections for reuse. A change to connection reuse therefore replaces neither TTL planning nor resolver checking. For sizing this connection layer, the article on NGINX Upstream Keepalive the resolver strategy.

Sources and Current State of Knowledge

Status of the research:

Research date: September 22, 2026. The examples of dynamic upstreams with a resolver in the upstream block and the `server … resolve` directive in NGINX Open Source refer to the documented support starting with version 1.27.3; for distribution packages, the build and vendor documentation are also authoritative.

https://nginx.org/en/docs/http/ngx_http_core_module.html

https://nginx.org/en/docs/http/ngx_http_upstream_module.html

https://nginx.org/en/docs/http/ngx_http_proxy_module.html

https://nginx.org/en/docs/switches.html

Current articles

Conceptual diagram of an NGINX reverse proxy with a DNS resolver cache and dynamic backend addresses.
Plesk web server

Configuring the NGINX Resolver Cache Correctly

Here's how to configure the NGINX resolver for dynamic backends: DNS TTL, valid, resolver_timeout, variable proxy_pass targets, and dynamic upstreams are clearly separated from one another.

Conceptual representation of kernel states that are visible via procfs.
Administration

Linux procfs for Administrators: An Overview of Important Files

procfs provides direct insight into the running Linux kernel. This guide explains important files under /proc, categorizes counters and snapshots, and outlines safe diagnostic paths for load, memory, processes, I/O, and sysctl parameters.

Conceptual diagram of a primary server with two replicas and a continuous replication stream.
Databases

Understanding the Redis Replication Backlog: PSYNC, Size, and HA Limits

The Redis replication backlog maintains a limited subset of the replication stream. After brief connection interruptions, it often allows for a PSYNC instead of a full resync, but it is not a substitute for persistent data storage or a well-designed high-availability strategy.