Skip to content

Don't log curl stderr for single-attempt IMDS lookups - #176

Open
mjnowen wants to merge 1 commit into
amazonlinux:mainfrom
mjnowen:fix/imds-single-attempt-curl-stderr
Open

mjnowen wants to merge 1 commit into
amazonlinux:mainfrom
mjnowen:fix/imds-single-attempt-curl-stderr

Conversation

@mjnowen

@mjnowen mjnowen commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #175

Description of changes

Since v2.7.5 (#162), get_meta() forwards curl's stderr to syslog at err priority on every attempt. Single-attempt callers query keys that may legitimately be absent, so every refresh of a secondary interface now logs:

ec2net[27201]: curl: (22) The requested URL returned error: 404

once for ipv4-prefix (no prefix delegated) and once for network-card (single-card instance types).

get_meta() already suppresses its own summary error for max_tries=1, for exactly this reason:

# Single-attempt callers query keys that may legitimately be absent
# don't log those.
if [ "$max_tries" -gt 1 ]; then
    error "[get_meta] ${key} failed after ${max_tries} tries"
fi

This change applies the same rule to curl's stderr. Retrying callers (max_tries > 1) keep forwarding curl's stderr at err priority, so the diagnostics added in #162 for transient IMDS failures are unchanged.

     while [ $attempts -lt $max_tries ]; do
-        meta=$(curl "${curl_opts[@]}" "$url" \
-            2> >(logger --id=$$ --priority "${syslog_facility}.err" --tag "$syslog_tag"))
+        if [ "$max_tries" -gt 1 ]; then
+            meta=$(curl "${curl_opts[@]}" "$url" \
+                2> >(logger --id=$$ --priority "${syslog_facility}.err" --tag "$syslog_tag"))
+        else
+            # Single-attempt callers query keys that may legitimately be
+            # absent (e.g. ipv4-prefix when no prefix is delegated, or
+            # network-card on single-card instance types), so a 404 is an
+            # expected outcome rather than an error. Discard curl's stderr to
+            # match the summary error suppression below.
+            meta=$(curl "${curl_opts[@]}" "$url" 2> /dev/null)
+        fi
         rc=$?

Behaviour

Caller curl stderr Summary error line Change
max_tries > 1 Forwarded at err (as today) Logged (as today) None
max_tries = 1 Discarded (as in v2.7.4) Not logged (as today) Restored

The four single-attempt call sites on main are ipv4-prefix/ipv6-prefix in create_rules(), device-number in _get_device_number(), and network-card in _get_network_card() (twice). All already treat a failed lookup as a normal outcome, and none of them lose a real error signal with this change:

  • create_rules() treats a missing prefix as "no prefixes delegated" (|| true).
  • _get_device_number() retries in its own loop and logs its own error ("Unable to identify device-number ...") if it finally gives up, so a genuine failure is still reported.
  • _get_network_card() retries in its own loop and, by design, treats running out of retries as "this instance type has no network-card key", recording that with the .no-network-card marker and returning 0. A 404 here is the expected signal on single-card instance types, not a failure.

Tests

Two regression tests are added to tests/imds.bats, following the existing style of mocking curl and logger as shell functions:

  • get_meta does not log curl errors for single-attempt optional keys: a single-attempt 404 produces no err-priority log line and no curl error text. The expected debug [get_meta] Querying IMDS trace is still allowed.
  • get_meta logs curl errors at err priority when retrying: with max_tries=2, curl's stderr still reaches logger at user.err. This guards against over-correcting and losing Fix bug where transient IMDS failure could revert secondary ip addres… #162's diagnostics.

Because the retrying path forwards stderr through an asynchronous process substitution, the tests poll briefly for the log rather than sleeping for a fixed time.

Verification

  • make check (ShellCheck --severity warning plus the full Bats suite): 39 ok, 0 failed, compared with 37 ok on main before the change.
  • With the lib/lib.sh change reverted and the new tests kept, get_meta does not log curl errors for single-attempt optional keys fails, confirming it catches the regression.
  • The two new tests passed 20 out of 20 repeated runs.
  • Observed on a real instance (im4gn.8xlarge, Ubuntu 26.04, systemd 259, one secondary ENI): the two err lines per refresh of the secondary interface come from ipv4-prefix and network-card, both returning HTTP 404.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Since v2.7.5 (amazonlinux#162), get_meta() forwards curl's stderr to syslog at err
priority on every attempt. Single-attempt callers query keys that may
legitimately be absent (ipv4-prefix when no prefix is delegated,
network-card on single-card instance types), so each refresh of a
secondary interface now logs 'curl: (22) The requested URL returned
error: 404' as an error.

get_meta() already suppresses its own summary error for max_tries=1 for
exactly this reason. Apply the same rule to curl's stderr, and keep
forwarding it at err priority for retrying callers.

Add regression tests in tests/imds.bats covering both paths.

Fixes amazonlinux#175
Comment thread lib/lib.sh
# network-card on single-card instance types), so a 404 is an
# expected outcome rather than an error. Discard curl's stderr to
# match the summary error suppression below.
meta=$(curl "${curl_opts[@]}" "$url" 2> /dev/null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this swallow the errors?

@mjnowen mjnowen Oct 1, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as designed. See full GH issue & PR description for context on why this is actually ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[regression] Don't log curl stderr for optional, single-attempt IMDS lookups

2 participants