fix(instances): skip IPv6 ExternalIP for Robot servers without a subnet - #1337
Merged
lukasmetzner merged 2 commits intoAug 28, 2026
Merged
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1337 +/- ##
==========================================
- Coverage 70.11% 66.69% -3.43%
==========================================
Files 29 29
Lines 2794 2816 +22
==========================================
- Hits 1959 1878 -81
- Misses 643 753 +110
+ Partials 192 185 -7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Jakob3xD
force-pushed
the
fix/robot-empty-ipv6-net
branch
from
August 27, 2026 10:36
60fc19b to
01ea5ce
Compare
Robot servers do not necessarily have an IPv6 subnet assigned. In that case the Robot API reports an empty `server_ipv6_net`, and appending "1" to it added the literal address "1" as an ExternalIP to the Node object. Guard the concatenation with an emptiness check and validate the result before using it, emitting a warning event when the reported subnet does not yield a valid address. Co-authored-by: Claude <noreply@anthropic.com>
Jakob3xD
force-pushed
the
fix/robot-empty-ipv6-net
branch
from
August 27, 2026 10:36
01ea5ce to
6c63b95
Compare
lukasmetzner
had a problem deploying
to
e2e-robot
August 28, 2026 07:55 — with
GitHub Actions
Failure
lukasmetzner
approved these changes
Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
robotNodeAddressesbuilds the IPv6 ExternalIP of a Robot server by appending1toserver.ServerIPv6Net(hcloud/instances.go):Robot servers do not necessarily have an IPv6 subnet assigned. In that case the Robot API reports an empty
server_ipv6_net, the concatenation yields the literal string1, and that ends up on the Node object:The same applies to any value that does not yield a valid address after the concatenation — a subnet reported with a prefix length, for example, produces
2001:db8:1234::/641.This affects
HCLOUD_INSTANCES_ADDRESS_FAMILY=ipv6anddualstack. The defaultipv4never enters this branch.The equivalent Cloud code path is already guarded (
ipv4 && !server.PublicNet.IPv4.IsUnspecified()/ipv6 && !server.PublicNet.IPv6.IsUnspecified()), because it works with realnet.IPvalues instead of string concatenation. The Robot path has no such check.Impact
The invalid entry is written to
status.addresseson every reconciliation and breaks consumers that parse node ExternalIPs. Found on a hybrid cluster whose Robot servers have no IPv6 subnet recorded in Robot.Fix
ServerIPv6Netis empty.net.ParseIPbefore adding it, and emit anInvalidIPv6Netwarning event when the reported subnet does not yield a valid address.Tests
Three cases added to
TestNodeAddressesRobotServer, covering ipv6-only and dual-stack without a subnet, and a malformed subnet. Without the fix they fail as: