hashicorp/nomad · error
template %q evaluated to empty result
Error message
template %q evaluated to empty result
What it means
parseSingleInterfaceTemplate renders a network_interface template and trims the result. If the user supplied a template (tpl != "") but the rendered output is empty, this error is returned: the template succeeded syntactically but matched no interface/IP. It prevents the agent from silently proceeding with a blank interface name.
Source
Thrown at command/agent/config.go:2454
return nil
}
// parseSingleInterfaceTemplate parses a go-sockaddr template and returns an
// error if it doesn't result in a single value.
func parseSingleInterfaceTemplate(tpl string) (string, error) {
out, err := template.Parse(tpl)
if err != nil {
// Typically something like:
// unable to parse template "{{printfl \"en50\"}}": template: sockaddr.Parse:1: function "printfl" not defined
return "", err
}
// Remove any extra empty space around the rendered result and check if the
// result is also not empty if the user provided a template.
out = strings.TrimSpace(out)
if tpl != "" && out == "" {
return "", fmt.Errorf("template %q evaluated to empty result", tpl)
}
// `template.Parse` returns a space-separated list of results, but on
// Windows network interfaces are allowed to have spaces, so there is no
// guaranteed separators that we can use to test if the template returned
// multiple interfaces.
// The test below checks if the template results to a single valid interface.
_, err = net.InterfaceByName(out)
if err != nil {
return "", fmt.Errorf("invalid interface name %q", out)
}
return out, nil
}
// parseMultipleIPTemplate is used as a helper function to parse out a multiple IP
// addresses from a config parameter.
func parseMultipleIPTemplate(ipTmpl string) ([]string, error) {View on GitHub (pinned to 482b49bf1a)
Solutions
- Change the template filter to match an interface that has an IP (e.g. GetInterfaceIP "eth0")
- Verify the target interface is UP and has an assigned address (ip addr)
- Use GetDefaultPrivateIP or an explicit IP literal if auto-detection is unreliable
- If a literal value was intended, remove the {{ }} braces so it is not treated as a template
Example fix
// before
client { network_interface = "{{ GetPrivateIP }}" } # host has no private IP
// after
client { network_interface = "{{ GetInterfaceIP \"eth0\" }}" } Defensive patterns
Strategy: validation
Validate before calling
out, err := renderTemplate(cfg.Client.NetworkInterface)
if err != nil || strings.TrimSpace(out) == "" {
// template rendered empty: choose another interface/filter
}
iface, _ := net.InterfaceByName(strings.TrimSpace(out)) // also confirm existence Prevention
- Check the target interface is UP with an assigned IP
- Avoid GetPrivateIP on hosts with only public IPs
- Wrap templates in staging tests before production
When it happens
Trigger: A template like {{ GetInterfaceIP "lo" }} or {{ GetPrivateIP }} evaluating to an empty string — e.g. interface has no addresses, no private IP exists, or the go-sockaddr filter matches nothing.
Common situations: Using GetPrivateIP on a host with only public addresses; referencing a loopback or down interface; running in minimal containers where the expected interface lacks an IPv4 address.
Related errors
- Failed to parse network-interface: %v
- Unable to parse address template %q: %v
- No addresses found, please configure one.
- Invalid task directory given: %q
- Invalid task environment given
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/f40a469aa71bc7d5.
Report an issue: GitHub.