apache/shenyu · error · NullPointerException

accessToken is null

Error message

accessToken is null

What it means

HeartbeatListener.sendHeartbeat sends instance beat info to each admin server with a cached access token; a blank token for a server throws NullPointerException. The token is populated by the listener's auth/login flow, so its absence means that admin node was never authenticated.

Solutions

  1. Verify shenyu.register credentials and serverLists are correct
  2. Check logs for the token/login failure for that admin URL
  3. Restart the client so authentication completes before heartbeating
  4. Ensure the admin node is reachable from the client host
Defensive patterns

Strategy: validation

Validate before calling

String t = accessToken.get(server); if (t == null || t.isEmpty()) { reLogin(server); }

Try / catch

try { listener.sendHeartbeat(beatInfo); } catch (RuntimeException e) { LOG.error("heartbeat failed; will re-auth and retry", e); }

Prevention

When it happens

Trigger: The heartbeat task fires (from the HeartbeatListener constructor/scheduler) before or without a successful token fetch for that server URL in serverLists.

Common situations: Wrong register credentials; admin node down at client startup so login never stored a token; network partition; race between first heartbeat tick and login completion.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/c018f6239128f547. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-register-center/shenyu-register-client-beat/src/main/java/org/apache/shenyu/register/client/beat/HeartbeatListener.java:122

            instanceBeatInfoDTO.setInstancePort(String.valueOf(serverProperties.getPort()));
            instanceBeatInfoDTO.setInstanceIp(IpUtils.getHost());
            instanceBeatInfoDTO.setNamespaceId(shenyuConfig.getNamespace());
            instanceBeatInfoDTO.setInstanceInfo(SystemInfoUtils.getSystemInfo());
            instanceBeatInfoDTO.setInstanceType(InstanceTypeConstants.BOOTSTRAP_INSTANCE_INFO);
            sendHeartbeat(instanceBeatInfoDTO);
            }, INITIAL_DELAY, CHECK_PERIOD, TimeUnit.SECONDS
        );
    }

    private void sendHeartbeat(final InstanceBeatInfoDTO instanceBeatInfoDTO) {
        int i = 0;
        for (String server : serverList) {
            i++;
            String concat = server.concat(Constants.BEAT_URI_PATH);
            try {
                String accessToken = this.accessToken.get(server);
                if (StringUtils.isBlank(accessToken)) {
                    throw new NullPointerException("accessToken is null");
                }
                RegisterUtils.doHeartBeat(GsonUtils.getInstance().toJson(instanceBeatInfoDTO), concat, Constants.HEARTBEAT, accessToken);
            } catch (Exception e) {
                LOG.error("HeartBeat admin url :{} is fail, will retry.", server, e);
                if (i == serverList.size()) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @EventListener(ContextClosedEvent.class)
    public void onShutdown() {
        executor.shutdown();
        try {
            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }

View on GitHub (pinned to 567142e072)