Npm ping triggering null pointer exception in Nexus3 3.13.0-01

this was not a problem until i upgraded from 3.11 to 3.13 on the weekend.

If I run npm ping against my nexus3 RM i get 500 and html returned instead of 200 and empty json

eg:

compare response from doing:

npm ping --registry=https://registry.npmjs.org/

which makes a GET to https://registry.npmjs.org/-/ping?write=true

and gets an empty json object - {} with HTTP 200

with the same to a nexus3 group containing a proxy of npmjs on nexus3

heres a log of the http request going through proxy:

    • [15/Aug/2018:08:45:07 +0000] “GET /repository/npm-npmjs/-/ping?write=true HTTP/1.1” 500 2038 “ping” “npm/6.2.0 node/v6.12.2 linux x64” “-”

Hi @peter.viertel. It looks like NXRM responded with a 500 status code. Do you see anything in your nexus.log file?

Yeah a big old java stacktrace. As you would expect.

Can you share the stack trace with me please?

java.lang.NullPointerException: null
	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:882)
	at org.sonatype.nexus.repository.npm.internal.NpmProxyFacetImpl.findCachedVersionsRemovedFromRemote(NpmProxyFacetImpl.java:306)
	at org.sonatype.nexus.repository.npm.internal.NpmProxyFacetImpl.mergeNewRootWithExistingRoot(NpmProxyFacetImpl.java:272)
	at org.sonatype.nexus.repository.npm.internal.NpmProxyFacetImpl.doPutPackageRoot(NpmProxyFacetImpl.java:251)
	at org.sonatype.nexus.transaction.TransactionalWrapper.proceedWithTransaction(TransactionalWrapper.java:56)
	at org.sonatype.nexus.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:54)
	at org.sonatype.nexus.repository.npm.internal.NpmProxyFacetImpl.putPackageRoot(NpmProxyFacetImpl.java:232)
	at org.sonatype.nexus.repository.npm.internal.NpmProxyFacetImpl.store(NpmProxyFacetImpl.java:134)
	at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.doGet(ProxyFacetSupport.java:222)
	at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.lambda$1(ProxyFacetSupport.java:209)
	at org.sonatype.nexus.repository.proxy.Cooperation$CooperatingFuture.download(Cooperation.java:262)
	at org.sonatype.nexus.repository.proxy.Cooperation.download(Cooperation.java:194)
	at org.sonatype.nexus.repository.proxy.Cooperation.cooperate(Cooperation.java:93)
	at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.get(ProxyFacetSupport.java:201)
	at org.sonatype.nexus.repository.proxy.ProxyHandler.handle(ProxyHandler.java:49)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.storage.UnitOfWorkHandler.handle(UnitOfWorkHandler.java:39)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.view.Context$proceed$5.call(Unknown Source)
	at org.sonatype.nexus.repository.npm.internal.NpmProxyRecipe$_closure1.doCall(NpmProxyRecipe.groovy:186)
	at sun.reflect.GeneratedMethodAccessor113.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1099)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
	at groovy.lang.Closure.call(Closure.java:418)
	at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
	at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
	at com.sun.proxy.$Proxy188.handle(Unknown Source)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.view.handlers.ContentHeadersHandler.handle(ContentHeadersHandler.java:44)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.view.handlers.ConditionalRequestHandler.handle(ConditionalRequestHandler.java:72)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.http.PartialFetchHandler.handle(PartialFetchHandler.java:59)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.cache.NegativeCacheHandler.handle(NegativeCacheHandler.java:56)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.npm.internal.NpmHandlers$1.handle(NpmHandlers.java:126)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.security.SecurityHandler.handle(SecurityHandler.java:52)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.view.handlers.TimingHandler.handle(TimingHandler.java:46)
	at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
	at org.sonatype.nexus.repository.view.Context.start(Context.java:114)
	at org.sonatype.nexus.repository.view.Router.dispatch(Router.java:64)
	at org.sonatype.nexus.repository.view.ConfigurableViewFacet.dispatch(ConfigurableViewFacet.java:52)
	at org.sonatype.nexus.repository.view.ConfigurableViewFacet.dispatch(ConfigurableViewFacet.java:43)
	at org.sonatype.nexus.repository.httpbridge.internal.ViewServlet.dispatchAndSend(ViewServlet.java:210)
	at org.sonatype.nexus.repository.httpbridge.internal.ViewServlet.doService(ViewServlet.java:172)
	at org.sonatype.nexus.repository.httpbridge.internal.ViewServlet.service(ViewServlet.java:126)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:286)
	at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:276)
	at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:181)
	at com.google.inject.servlet.DynamicServletPipeline.service(DynamicServletPipeline.java:71)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:112)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	at org.sonatype.nexus.security.SecurityFilter.executeChain(SecurityFilter.java:85)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.sonatype.nexus.security.SecurityFilter.doFilterInternal(SecurityFilter.java:101)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.repository.httpbridge.internal.ExhaustRequestFilter.doFilter(ExhaustRequestFilter.java:80)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at com.sonatype.nexus.licensing.internal.LicensingRedirectFilter.doFilter(LicensingRedirectFilter.java:108)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:97)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.internal.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:68)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.internal.web.EnvironmentFilter.doFilter(EnvironmentFilter.java:101)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.internal.web.HeaderPatternFilter.doFilter(HeaderPatternFilter.java:98)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at com.google.inject.servlet.DynamicFilterPipeline.dispatch(DynamicFilterPipeline.java:104)
	at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:135)
	at org.sonatype.nexus.bootstrap.osgi.DelegatingFilter.doFilter(DelegatingFilter.java:73)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1317)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1219)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:175)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:531)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:680)
	at java.lang.Thread.run(Thread.java:748)

@peter.viertel I’m surprised this worked for you in 3.11 as this isn’t an endpoint we’ve added support for yet (see https://issues.sonatype.org/browse/NEXUS-13434) it must have been working as an unintended side-effect of another feature. I’ve added a reference to this thread as a comment on that ticket.

Ah i see… seems npm ping is considered a non critical feature? it has become a problem for us because a package some devs are using called lerna invokes npm ping - it is becoming a struggle to keep it working in our environment…

however i can make it work in 3.13 now!

i created a new npm proxy and that works… so this problem looks to be a result of upgrading from an older revision to 3.13 - this nexus repo was created around january this year - i use the docker.hub/sonatype/nexus3 image for it and i have updated the version perhaps twice since then.

so now i have fixed the npm-group, but not the hosted repo i publish to - that still displays the error and i have to contemplate how to fix this still…

see here for npm ping

$ npm -d ping --registry=https://nexus.xxxxxxxxx.com.au/repository/npm-proxy/
npm info it worked if it ends with ok
npm info using npm@6.2.0
npm info using node@v6.12.2
npm info attempt registry request try #1 at 11:07:06 PM
npm http request GET https://nexus.xxxxxxx.com.au/repository/npm-proxy/-/ping?write=true
npm http 200 https://nexus.xxxxxxx.com.au/repository/npm-proxy/-/ping?write=true
Ping success: {"versions":{},"_rev":"0","time":{"created":"2018-08-15T13:07:07.507Z","modified":"2018-08-15T13:07:07.507Z"},"_id":"--ping","_lastModified":"Wed, 15 Aug 2018 13:07:07 GMT"}
npm timing npm Completed in 1105ms
npm info ok

@peter.viertel Does it continue to work even after you have proxied some packages? It looks like the NPE appears when NXRM tries to merge the proxied npm package root (metadata) with a locally stored package root. If you have an empty repository then NXRM will skip that step. You can see more information about why this is the case in the comments of https://issues.sonatype.org/browse/NEXUS-13434.

This shouldn’t work for hosted because we haven’t implemented the endpoints, it is a fluke that it works for proxy. Note: you should be cautious about relying on it working because it is not something that is intentionally supported and could disappear under certain circumstances.

I forgot to mention in my previous reply you can vote on NEXUS-13434 to increase its priority. Also the source for NXRM’s npm plugin is public if you’re interested in contributing.