Error editing WFS-T authenticated layers - NulllPointerException

I am using default Geoserver 2.25, to serve a PostGIS table as WFS-T.
I am viewing the layer in web maps, and editing the layer through QGIS.

The layer is viewable and editable no problem, until I restrict the layers users.
When the layer requires basic auth to both view and edit, I can still view it in QGIS(showing that the credentials are working), but saving edits to a feature triggers errors from Geoserver.

The errors are returned from the REQUEST=DescribeFeatureType request from QGIS to Geoserver. I can see that the basic auth is being included in the request. The return from Geoserver is:

<?xml version="1.0" ?>
<ServiceExceptionReport
   version="1.2.0"
   xmlns="http://www.opengis.net/ogc"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd">
    <ServiceException>
      java.lang.NullPointerException
</ServiceException>
</ServiceExceptionReport>

Why would this happen? I can see that someone had an indentical issue on GIS Stackexchange that was never resolved: WFS-T editing of PostGIS table using QGIS? - Geographic Information Systems Stack Exchange

Hi @staf_ivory_smith welcome to the user forum thanks for joining us here.

To troubleshoot we need to look at the logs, which has more details about the ServiceException NullPointerException. Specifically we are looking for the stack trace which says where in the application the problem occurred.

NullPointerException tends to indicate information is missing to not available. So by looking where the problem occured we can check what information it was trying to find.

Dear @jive thanks for the welcome, happy to be here and thankyou for you help.

The logs relevant to lading the layer and then trying to edit it are here:

14 Nov 08:45:32 INFO   [geoserver.wfs] - 
Request: getServiceInfo
14 Nov 08:45:32 INFO   [geoserver.wfs] - 
Request: getCapabilities
    acceptVersions:
        version[0] = 2.0.0
    baseUrl = http://GEOSERVER_BASE_URL/geoserver/
    namespace = dvp
    service = WFS
14 Nov 08:45:40 INFO   [geoserver.wfs] - 
Request: getServiceInfo
14 Nov 08:45:40 INFO   [geoserver.wfs] - 
Request: getCapabilities
    acceptVersions:
        version[0] = 2.0.0
    baseUrl = http://GEOSERVER_BASE_URL/geoserver/
    namespace = dvp
    service = WFS
14 Nov 08:45:40 INFO   [geoserver.wfs] - 
Request: getServiceInfo
14 Nov 08:45:40 INFO   [geoserver.wfs] - 
Request: describeFeatureType
    service = WFS
    version = 2.0.0
    baseUrl = http://GEOSERVER_BASE_URL/geoserver/
    typeName[0] = {dvp}DVP_MASTER
    outputFormat = application/gml+xml; version=3.2
14 Nov 08:45:40 INFO   [geoserver.wfs] - 
Request: getServiceInfo
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - CREATE CONNECTION
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - SELECT count(*) AS gt_result_ FROM (SELECT * FROM "public"."DVP_MASTER" LIMIT 1) gt_limited_
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - CLOSE CONNECTION
14 Nov 08:45:40 INFO   [geoserver.wfs] - 
Request: getFeature
    service = WFS
    version = 2.0.0
    baseUrl = http://GEOSERVER_BASE_URL/geoserver/
    count = 1
    outputFormat = application/gml+xml; version=3.2
    resolve = none
    resolveDepth = *
    resolveTimeout = 300
    resultType = results
    startIndex = 0
    abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@7e3d1c37 (handle: null) (abstractProjectionClause: null, abstractSelectionClause: null, abstractSortingClause: null, aliases: null, typeNames: [{dvp}DVP_MASTER]) (featureVersion: null, srsName: EPSG:4326, filter: null, propertyNames: null, sortBy: null)
    abstractQueryExpression[0]:
        typeNames[0] = {dvp}DVP_MASTER
        srsName = EPSG:4326
14 Nov 08:45:40 DEBUG  [geotools.xsd] - building schema for schema: dvp
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - CREATE CONNECTION
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - SELECT count(*) FROM "public"."DVP_MASTER"
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - CLOSE CONNECTION
14 Nov 08:45:40 DEBUG  [data.util] - CRSConverterFactory can be applied from Strings to CRS  only.
14 Nov 08:45:40 DEBUG  [data.util] - InterpolationConverterFactory can be applied from Strings to Interpolation only.
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - CREATE CONNECTION
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - SELECT "id",encode(ST_AsEWKB("geom"), 'base64') as "geom","fid","accuracy","sitenumnew","site_name","alt_name","legend","dambimangari_name","country","site_experience","location_experience","type","new_and_proposed_by_who","cultural_story","natural_history_story_special_features","additional_conditions","photos_of_site_in_database","notes_from_to_consult","additional_notes","access_issues","pams_comments","stafs_comments","alt_permit","sitenumold","pass_level","map_colour","nositenumnew","lat","long","web_map_show" FROM "public"."DVP_MASTER" ORDER BY "id" ASC LIMIT 1
14 Nov 08:45:40 DEBUG  [geotools.jdbc] - CLOSE CONNECTION
14 Nov 08:45:41 INFO   [geoserver.wfs] - 
Request: getServiceInfo
14 Nov 08:45:41 DEBUG  [geotools.jdbc] - CREATE CONNECTION
14 Nov 08:45:41 DEBUG  [geotools.jdbc] - SELECT count(*) AS gt_result_ FROM (SELECT * FROM "public"."DVP_MASTER" LIMIT 1000000) gt_limited_
14 Nov 08:45:41 DEBUG  [geotools.jdbc] - CLOSE CONNECTION
14 Nov 08:45:41 INFO   [geoserver.wfs] - 
Request: getFeature
    service = WFS
    version = 2.0.0
    baseUrl = http://GEOSERVER_BASE_URL/geoserver/
    count = 1000000
    outputFormat = application/gml+xml; version=3.2
    resolve = none
    resolveDepth = *
    resolveTimeout = 300
    resultType = results
    startIndex = 0
    abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@3ceeaea9 (handle: null) (abstractProjectionClause: null, abstractSelectionClause: null, abstractSortingClause: null, aliases: null, typeNames: [{dvp}DVP_MASTER]) (featureVersion: null, srsName: EPSG:4326, filter: null, propertyNames: null, sortBy: null)
    abstractQueryExpression[0]:
        typeNames[0] = {dvp}DVP_MASTER
        srsName = EPSG:4326
14 Nov 08:45:41 DEBUG  [geotools.xsd] - building schema for schema: dvp
14 Nov 08:45:41 DEBUG  [data.util] - CRSConverterFactory can be applied from Strings to CRS  only.
14 Nov 08:45:41 DEBUG  [data.util] - InterpolationConverterFactory can be applied from Strings to Interpolation only.
14 Nov 08:45:41 DEBUG  [geotools.jdbc] - CREATE CONNECTION
14 Nov 08:45:41 DEBUG  [geotools.jdbc] - SELECT "id",encode(ST_AsEWKB("geom"), 'base64') as "geom","fid","accuracy","sitenumnew","site_name","alt_name","legend","dambimangari_name","country","site_experience","location_experience","type","new_and_proposed_by_who","cultural_story","natural_history_story_special_features","additional_conditions","photos_of_site_in_database","notes_from_to_consult","additional_notes","access_issues","pams_comments","stafs_comments","alt_permit","sitenumold","pass_level","map_colour","nositenumnew","lat","long","web_map_show" FROM "public"."DVP_MASTER" ORDER BY "id" ASC LIMIT 1000000
14 Nov 08:45:41 DEBUG  [geotools.jdbc] - CLOSE CONNECTION
14 Nov 08:46:28 INFO   [geoserver.wfs] - 
Request: getServiceInfo
14 Nov 08:46:28 TRACE  [xsd.impl] - schemaLocation found: dvp https://GEOSERVER_BASE_URL/geoserver/dvp/wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=dvp:DVP_MASTER
14 Nov 08:46:28 INFO   [xsd.impl] - https://GEOSERVER_BASE_URL/geoserver/dvp/wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=dvp:DVP_MASTER
14 Nov 08:46:28 INFO   [geoserver.wfs] - 
Request: getServiceInfo
14 Nov 08:46:28 INFO   [geoserver.ows] - 
org.geoserver.wfs.WFSException: Could not find type: {dvp}DVP_MASTER
	at org.geoserver.wfs.DescribeFeatureType.run(DescribeFeatureType.java:155)
	at org.geoserver.wfs.DefaultWebFeatureService.describeFeatureType(DefaultWebFeatureService.java:94)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.geoserver.ows.util.RequestObjectLogger.invoke(RequestObjectLogger.java:51)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241)
	at com.sun.proxy.$Proxy118.describeFeatureType(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.geoserver.ows.Dispatcher.execute(Dispatcher.java:867)
	at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:268)
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:51)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.ThreadLocalsCleanupFilter.doFilter(ThreadLocalsCleanupFilter.java:28)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:73)
	at org.geoserver.ows.HTTPHeadersCollector.doFilter(HTTPHeadersCollector.java:48)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:70)
	at org.geoserver.filters.HTTPMethodFilter.doFilter(HTTPMethodFilter.java:36)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:70)
	at org.geoserver.filters.LoggingFilter.doFilter(LoggingFilter.java:194)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:70)
	at org.geoserver.filters.SpringDelegatingFilter.doFilter(SpringDelegatingFilter.java:43)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.platform.AdvancedDispatchFilter.doFilter(AdvancedDispatchFilter.java:39)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:337)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerAnonymousAuthenticationFilter.doFilter(GeoServerAnonymousAuthenticationFilter.java:53)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:164)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.geoserver.security.filter.GeoServerBasicAuthenticationFilter.doFilter(GeoServerBasicAuthenticationFilter.java:81)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.oauth2.GeoServerOAuthAuthenticationFilter.doFilter(GeoServerOAuthAuthenticationFilter.java:169)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1.doFilterInternal(GeoServerSecurityContextPersistenceFilter.java:72)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)
	at org.geoserver.security.GeoServerSecurityFilterChainProxy.doFilter(GeoServerSecurityFilterChainProxy.java:141)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.XFrameOptionsFilter.doFilter(XFrameOptionsFilter.java:100)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.GZIPFilter.doFilter(GZIPFilter.java:54)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.SessionDebugFilter.doFilter(SessionDebugFilter.java:49)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.FlushSafeFilter.doFilter(FlushSafeFilter.java:42)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:357)
	at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:176)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:829)
14 Nov 08:46:28 DEBUG  [xsd.impl] - schema specified by parser configuration not found, supplementing...
14 Nov 08:46:28 ERROR  [geoserver.ows] - 
java.lang.NullPointerException
	at org.geotools.xsd.impl.SchemaIndexImpl.buildElementIndex(SchemaIndexImpl.java:375)
	at org.geotools.xsd.impl.SchemaIndexImpl.getElementIndex(SchemaIndexImpl.java:315)
	at org.geotools.xsd.impl.SchemaIndexImpl.getElementDeclaration(SchemaIndexImpl.java:120)
	at org.geotools.xsd.impl.HandlerFactoryImpl.createElementHandler(HandlerFactoryImpl.java:34)
	at org.geotools.xsd.impl.DocumentHandlerImpl.createChildHandler(DocumentHandlerImpl.java:71)
	at org.geotools.xsd.impl.ParserHandler.getHandler(ParserHandler.java:390)
	at org.geotools.xsd.impl.ParserHandler.startElement(ParserHandler.java:359)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:510)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3063)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:836)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1216)
	at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:635)
	at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:324)
	at org.geotools.xsd.Parser.parse(Parser.java:183)
	at org.geotools.xsd.Parser.parse(Parser.java:138)
	at org.geoserver.wfs.xml.v1_0_0.WfsXmlReader.read(WfsXmlReader.java:75)
	at org.geoserver.ows.Dispatcher.parseRequestXML(Dispatcher.java:1546)
	at org.geoserver.ows.Dispatcher.dispatch(Dispatcher.java:691)
	at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:258)
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:51)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.ThreadLocalsCleanupFilter.doFilter(ThreadLocalsCleanupFilter.java:28)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:73)
	at org.geoserver.ows.HTTPHeadersCollector.doFilter(HTTPHeadersCollector.java:48)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:70)
	at org.geoserver.filters.HTTPMethodFilter.doFilter(HTTPMethodFilter.java:36)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:70)
	at org.geoserver.filters.LoggingFilter.doFilter(LoggingFilter.java:194)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:70)
	at org.geoserver.filters.SpringDelegatingFilter.doFilter(SpringDelegatingFilter.java:43)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.platform.AdvancedDispatchFilter.doFilter(AdvancedDispatchFilter.java:39)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:337)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerAnonymousAuthenticationFilter.doFilter(GeoServerAnonymousAuthenticationFilter.java:53)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:196)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.geoserver.security.filter.GeoServerBasicAuthenticationFilter.doFilter(GeoServerBasicAuthenticationFilter.java:81)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.oauth2.GeoServerOAuthAuthenticationFilter.doFilter(GeoServerOAuthAuthenticationFilter.java:169)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:71)
	at org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1.doFilterInternal(GeoServerSecurityContextPersistenceFilter.java:72)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:75)
	at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)
	at org.geoserver.security.GeoServerSecurityFilterChainProxy.doFilter(GeoServerSecurityFilterChainProxy.java:141)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.XFrameOptionsFilter.doFilter(XFrameOptionsFilter.java:100)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.GZIPFilter.doFilter(GZIPFilter.java:48)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.SessionDebugFilter.doFilter(SessionDebugFilter.java:49)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.geoserver.filters.FlushSafeFilter.doFilter(FlushSafeFilter.java:42)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:357)
	at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:176)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:829)

Does this clarify the issue? I have added all, as it shows that the layer can be read succesfully with authentication, but not edited.

I guess so, the problem seems to be:

org.geoserver.wfs.WFSException: Could not find type: {dvp}DVP_MASTER

The content being sent from QGIS needs to reference an XML Schema document (so we can be sure it is valid before accepting any additions or updates).

The schema document is provided by describeFeatureType … but the type name provided by QGIS is {dvp}DVP_MASTER.

Do you know what {dvp} is or where it comes from?

Yeah the logs clearly show describe feature request with typeName[0] = {dvp}DVP_MASTER which will not work. This should be reported to QGIS as a bug report.

If you turn on request body logging you can likely clearly see the XML content that is being sent with the a “dvp” namespace defined by this invalid describe feature type request.

Dear @jody.garnett , dvp is just the name of my geoserver workspace.

So the incorrect part, is that QGIS is requesting {dvp}DVP_MASTER but should be dvp.DVP_MASTER ? Is it the curly braces that are the problem?

Here is what QGIS says it is sending:

<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="dvp https://maps.rightplacegeo.com/geoserver/dvp/wfs?SERVICE=WFS&amp;REQUEST=DescribeFeatureType&amp;VERSION=1.0.0&amp;TYPENAME=dvp:DVP_MASTER" xmlns:gml="http://www.opengis.net/gml" xmlns:dvp="dvp"><Update xmlns="http://www.opengis.net/wfs" typeName="dvp:DVP_MASTER"><Property xmlns="http://www.opengis.net/wfs"><Name xmlns="http://www.opengis.net/wfs">dvp:geom</Name><Value xmlns="http://www.opengis.net/wfs"><gml:Point srsName="EPSG:4326"><gml:coordinates ts=" " cs=",">124.16233811800992726,-15.90893759154065989</gml:coordinates></gml:Point></Value></Property><Filter xmlns="http://www.opengis.net/ogc"><FeatureId xmlns="http://www.opengis.net/ogc" fid="DVP_MASTER.69"/></Filter></Update></Transaction>

And if I copy that request into Postman and send again I get the same response. I think its possible the error is on the Geoserver side?

This is from the Geoserver logs. Im not sure what QGIS is doing wrong here…:

18 Nov 01:10:02 INFO   [geoserver.filters] - 206.83.111.252 "GET /geoserver/dvp/wfs?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=dvp:DVP_MASTER&STARTINDEX=0&COUNT=1000000&SRSNAME=EPSG:4326" took 88ms
18 Nov 01:10:23 INFO   [geoserver.filters] - 206.83.111.252 "POST /geoserver/dvp/wfs?SERVICE=WFS" "Mozilla/5.0 QGIS/34000/macOS 14.5" "" "text/xml"  request-size: 859 body: 
<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="dvp https://maps.rightplacegeo.com/geoserver/dvp/wfs?SERVICE=WFS&amp;REQUEST=DescribeFeatureType&amp;VERSION=1.0.0&amp;TYPENAME=dvp:DVP_MASTER" xmlns:gml="http://www.opengis.net/gml" xmlns:dvp="dvp"><Update xmlns="http://www.opengis.net/wfs" typeName="dvp:DVP_MASTER"><Property xmlns="http://www.opengis.net/wfs"><Name xmlns="http://www.opengis.net/wfs">dvp:geom</Name><Value xmlns="http://www.opengis.net/wfs"><gml:Point srsName="EPSG:4326"><gml:coordinates ts=" " cs=",">124.16233811800992726,-15.90893759154065989</gml:coordinates></gml:Point></Value></Property><Filter xmlns="http://www.opengis.net/ogc"><FeatureId xmlns="http://www.opengis.net/ogc" fid="DVP_MASTER.69"/></Filter></Update></Transaction>

Hi,
I don’t think you should be mislead by the naming of {dvp}DVP_MASTER vs dvp:DVP_MASTER. The first one is the result of a QName.toString().

Regards,
Roar Brænden

Thanks Roar that makes sense about Name.

Do you have any insight into what may be the problem?

I guess I want to focus on the DescribeFeatureType request contained in the xmlns declaration. I wonder if GeoServer is passing the credentials along successfully…

Checking GetCapabilities GeoServer Web Feature Service

And it does not list a layer DVP_MASTER (I assume because I have not provided security credentials).

The only layer shown dvp_sites_public works:

Dear @jive, yes thats right. The DVP_MASTER is only viewable with credentials. I have checked and QGIS is passing along credentials correctly - well there is a header: Authorization: Basic .................. which decodes to a valid username and password. What could I do at my end? Could I create a test layer with the same fields and dummy data, and create a test user that has write access for someone (e.g. yourself if possible) to test?

You could report the bug to the issue tracker - and it would be very helpful to include the steps required to reproduce the problem with the release data directory.

Although it may not be obvious, the problem is occurring when GeoServer itself is trying to parse the Transaction request, and the XML Parser needs to make the request to DescribeFeatureType. I am not sure how we can provide the correct credentials to the XML Parser; but hopefully someone else here will have an idea how to fix.

1 Like

OK I will submit the bug report tonight or tomorrow, Ill setup a new dummy layer for testing. GeoServer - JIRA

I think I had a similar issue from within gt-wfs-ng, when proxying a WFS that had restrictive access. The solution then was to override the URIHandler with a class that would use the user credentials specified in the configuration. Then we injected an instance of that into the ParserHandler.uriHandlers. Your problem is completely different though, since you would have to use the requesting user’s credentials.
What if you opened the layer for read access for everyone?

Not possible, the intention is to hold sensitive location information about sacred sites unfortunately. Really just need to find a way to have a private editable vector layer and I was hoping WFS-T is the way to go while waiting for OGC Api Features transactions :slight_smile:

That is actually the kind of fix I think is needed inside GeoServer (configure the GeoTools parser with the credentials to pass along). The requesting user’s credentials are available in a thread local, so we should be able to check? Maybe that is the problem, if the parsing is happening in another thread for performance then it would not longer have access to the thread local.

@roarbra does that match with your experience of ParserHandler.uriHandlers?

Yes, thats correct, but I’ve started to wonder why it fetches this schema. This would be an internal url, so there shouldn’t be a need for a http call.

The GIS part of geoserver is handled by the java GIS library GeoTools, and indeed the XML parsing is handled by Java. Configuring both these systems to “know about” internal URLs would be a lot of work, and since the schemas are generated on the fly (based on the data format / database table) the URL is used directly.

This is why we can see a separate DescribeFeatureType response come in as the Transaction request is being parsed.