Skip to content

fix: handle exceptions during Nacos service shutdown to prevent NPE propagation#4286

Open
daguimu wants to merge 1 commit intoalibaba:2025.1.xfrom
daguimu:fix/nacos-graceful-shutdown-npe-issue4081
Open

fix: handle exceptions during Nacos service shutdown to prevent NPE propagation#4286
daguimu wants to merge 1 commit intoalibaba:2025.1.xfrom
daguimu:fix/nacos-graceful-shutdown-npe-issue4081

Conversation

@daguimu
Copy link
Copy Markdown
Contributor

@daguimu daguimu commented Mar 27, 2026

Describe what this PR does / why we need it

During application shutdown, NacosServiceManager.nacosServiceShutDown() calls namingService.shutDown() which internally invokes NotifyCenter.deregisterSubscriber(). If the JVM shutdown hooks have already destroyed NotifyCenter.INSTANCE, this throws a NullPointerException:

java.lang.NullPointerException: Cannot read field "sharePublisher" because "com.alibaba.nacos.common.notify.NotifyCenter.INSTANCE" is null
  at com.alibaba.nacos.common.notify.NotifyCenter.deregisterSubscriber(NotifyCenter.java:242)
  at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.shutdown(...)
  at com.alibaba.cloud.nacos.NacosServiceManager.nacosServiceShutDown(...)
  at com.alibaba.cloud.nacos.registry.NacosServiceRegistry.close(...)

This NPE escapes NacosServiceRegistry.close() (which only catches NacosException) and propagates to NacosGracefulShutdownDelegate, causing an alarming ERROR log during every application shutdown.

Additionally, when namingService.shutDown() throws, namingMaintainService.shutDown() never gets a chance to execute.

Does this pull request fix one issue?

Fixes #4081
Fixes #4247

Describe how you did it

Wrapped each shutDown() call in NacosServiceManager.nacosServiceShutDown() with independent try-catch blocks:

  • NacosException is caught and logged at ERROR level (real failures)
  • Other exceptions (including the NPE race condition) are caught and logged at WARN level (expected during shutdown ordering)
  • Service references are always nulled out after shutdown attempt
  • Both namingService and namingMaintainService always get their shutdown attempts, even if one fails

Describe how to verify it

  1. Start a Spring Cloud Alibaba application with Nacos discovery
  2. Stop the application
  3. Verify no ERROR log from NacosGracefulShutdownDelegate during shutdown
  4. Run NacosServiceManagerTests — all 6 tests pass

Tests Added

Change Point Test
namingService.shutDown() NPE caught at WARN testNamingServiceNpeShutdownShouldNotPropagate()
namingMaintainService.shutDown() NPE caught at WARN testNamingMaintainServiceNpeShutdownShouldNotPropagate()
Both services get shutdown attempt when first fails testBothServicesFailShouldStillCleanUp()
NacosException caught and logged at ERROR testNacosExceptionDuringShutdownShouldNotPropagate()
Normal shutdown still works testNormalShutdownShouldSucceed()
Null services handled safely testNullServicesShouldNotFail()

Special notes for reviews

  • The method signature throws NacosException is preserved for backward compatibility, though exceptions are now handled internally
  • NacosServiceRegistry.close() catch block becomes dead code but is left unchanged to minimize diff
  • The existing NacosGracefulShutdownDelegateTests (4 tests) continue to pass

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 27, 2026

CLA assistant check
All committers have signed the CLA.

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.

应用关闭时报错 Error occurred while performing Nacos client graceful shutdown

2 participants