valyala/fasthttp · error

prefork: resolve %s/%s: %w

Error message

prefork: resolve %s/%s: %w

What it means

In prefork's setTCPListenerFiles, net.ResolveTCPAddr failed to resolve the given address with the configured network (tcp/tcp4/tcp6). The error is wrapped as 'prefork: resolve <network>/<addr>'. This happens before any socket is created, so it is a pure address/network resolution failure — bad address literal, unsupported network string, or unresolvable host.

Source

Thrown at prefork/prefork.go:309

	}

	p.ln = ln

	if p.OnMasterDeath != nil {
		go p.watchMaster(os.Getppid())
	}

	return ln, nil
}

func (p *Prefork) setTCPListenerFiles(addr string) error {
	if p.Network == "" {
		p.Network = defaultNetwork
	}

	tcpAddr, err := net.ResolveTCPAddr(p.Network, addr)
	if err != nil {
		return fmt.Errorf("prefork: resolve %s/%s: %w", p.Network, addr, err)
	}

	tcpListener, err := net.ListenTCP(p.Network, tcpAddr)
	if err != nil {
		return fmt.Errorf("prefork: listen tcp %s: %w", addr, err)
	}

	listenerFile, err := tcpListenerFile(tcpListener)
	if err != nil {
		// Close the bound listener so we don't leak the socket/fd when
		// File() fails. p.ln is intentionally only assigned after this
		// point so the caller never sees a half-initialised state.
		_ = tcpListener.Close()
		return fmt.Errorf("prefork: dup listener fd: %w", err)
	}

	p.ln = tcpListener
	p.files = []*os.File{listenerFile}

View on GitHub (pinned to c96f600972)

Solutions

  1. Fix the listen address to a valid literal like ":8080" or "0.0.0.0:8080"; verify with net.ResolveTCPAddr(p.Network, addr) in isolation.
  2. Match the network to the address: use "tcp" (default) unless you need tcp4/tcp6, and use an IPv6 literal with tcp6.
  3. If using a hostname, ensure DNS resolution works in the environment, or replace it with an IP literal.
  4. Check the prefork Network configuration isn't overwritten (e.g. set to "unix") before setTCPListenerFiles runs.

Example fix

// before
p.Network = "tcp6"
addr := "0.0.0.0:8080" // IPv4 literal with tcp6 -> resolve error
// after
p.Network = "tcp"
addr := ":8080"
Defensive patterns

Strategy: validation

Validate before calling

// Validate the prefork address/network before starting:
func validatePreforkAddr(network, addr string) error {
    if network == "" { network = "tcp" }
    switch network {
    case "tcp", "tcp4", "tcp6":
    default:
        return fmt.Errorf("unsupported prefork network %q", network)
    }
    if _, err := net.ResolveTCPAddr(network, addr); err != nil {
        return fmt.Errorf("invalid prefork addr %s/%s: %w", network, addr, err)
    }
    return nil
}

Type guard

func isResolveError(err error) bool {
    return err != nil && strings.HasPrefix(err.Error(), "prefork: resolve ")
}

Try / catch

if err := validatePreforkAddr(p.Network, addr); err != nil {
    return fmt.Errorf("startup aborted: %w", err) // fail fast, before Prefork
}
if err := fasthttp.Prefork(...); err != nil {
    if strings.HasPrefix(err.Error(), "prefork: resolve ") {
        log.Printf("bad prefork address: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling fasthttp Prefork with an addr like ":port", "localhost:8080", or a malformed literal (":::8080") when ResolveTCPAddr rejects it; p.Network set to an unsupported value.

Common situations: Config typo in the listen address; passing a hostname where the environment lacks DNS; mixing "tcp6" network with an IPv4 address; empty address parsing failures.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/ecfdac92cc6e50c4. Report an issue: GitHub.