Repository navigation
Change in 3.4.0: missing event source error is now returned from "XmlConfigurator.ConfigureAndWatch" #332
Description
There must have been a change in 3.4.0 that makes my code fail on my development machine: my Log4Net config defines an EventLogAppender, and this fails if the event log registry key is not set:
[EventLogAppender] ErrorCode: GenericFailure. Caught a SecurityException trying to access the EventLog. Most likely the event source Sample Application doesn't exist and must be created by a local administrator. Will disable EventLogAppender. See http://logging.apache.org/log4net/release/faq.html#trouble-EventLog
My Log4Net config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="EventLogAppender" type="Log4Net.Appenders.NetCore.EventLogAppender,Log4Net.Appenders.NetCore">
<param name="LogName" value="Sample Log" />
<param name="ApplicationName" value="Sample Application" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="EventLogAppender" />
</root>
</log4net>When activating Log4Net, I use XmlConfigurator.ConfigureAndWatch and fail if the resulting error collection contains anything - in this case logging is misconfigured and don't want to continue.
With 3.4.0, the error messages contain an error (see above) if there is no key Computer\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\EventLog\Sample Log\Sample Application. So my Log4Net initialization fails.
With 3.3.2, there is no error message, the errors are caught internally.
The error happens internally, the stack trace is the same for both versions:
System.Security.SecurityException
HResult=0x8013150A
Message=Requested registry access is not allowed.
Source=Microsoft.Win32.Registry
StackTrace:
at
Microsoft.Win32.Registry.dll!Microsoft.Win32.RegistryKey.OpenSubKey(string name, bool writable) Unknown
System.Diagnostics.EventLog.dll!System.Diagnostics.EventLog.GetEventLogRegKey(string machine, bool writable) Unknown
System.Diagnostics.EventLog.dll!System.Diagnostics.EventLog.FindSourceRegistration(string source, string machineName, bool readOnly, bool wantToCreate) Unknown
System.Diagnostics.EventLog.dll!System.Diagnostics.EventLog.FindSourceRegistration(string source, string machineName, bool readOnly) Unknown
System.Diagnostics.EventLog.dll!System.Diagnostics.EventLog.DeleteEventSource(string source, string machineName) Unknown
Log4Net.Appenders.NetCore.dll!Log4Net.Appenders.NetCore.EventLogAppender.ActivateOptions() Unknown
log4net.dll!log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(System.Xml.XmlElement appenderElement) Unknown
log4net.dll!log4net.Repository.Hierarchy.XmlHierarchyConfigurator.FindAppenderByReference(System.Xml.XmlElement appenderRef) Unknown
log4net.dll!log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseChildrenOfLoggerElement(System.Xml.XmlElement catElement, log4net.Repository.Hierarchy.Logger log, bool isRoot) Unknown
log4net.dll!log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseRoot(System.Xml.XmlElement rootElement) Unknown
log4net.dll!log4net.Repository.Hierarchy.XmlHierarchyConfigurator.Configure(System.Xml.XmlElement element) Unknown
log4net.dll!log4net.Repository.Hierarchy.Hierarchy.XmlRepositoryConfigure(System.Xml.XmlElement element) Unknown
log4net.dll!log4net.Repository.Hierarchy.Hierarchy.log4net.Repository.IXmlRepositoryConfigurator.Configure(System.Xml.XmlElement element) Unknown
log4net.dll!log4net.Config.XmlConfigurator.InternalConfigureFromXml(log4net.Repository.ILoggerRepository repository, System.Xml.XmlElement element) Unknown
log4net.dll!log4net.Config.XmlConfigurator.InternalConfigure(log4net.Repository.ILoggerRepository repository, System.IO.Stream configStream) Unknown
log4net.dll!log4net.Config.XmlConfigurator.InternalConfigure(log4net.Repository.ILoggerRepository repository, System.IO.FileInfo configFile) Unknown
log4net.dll!log4net.Config.XmlConfigurator.InternalConfigureAndWatch(log4net.Repository.ILoggerRepository repository, System.IO.FileInfo configFile) Unknown
log4net.dll!log4net.Config.XmlConfigurator.ConfigureAndWatch(System.IO.FileInfo configFile) Unknown
> Log4NetTest_332.dll!Log4NetTest_332.Program.Main(string[] args) Line 15 C#
Attached is a sample project, containing the same client code for 3.4.0 and 3.3.2:
I did not find anything about this change in the release notes, and at first glance I did not see the change which caused this.
So, first question is: is this change intentional or some kind of regression😄 ?
If it is intentional, I probably would have to catch this kind of error and handle it somehow.
Activity
FreeAndNil commentedon Sep 28, 2026
Hi @WolfgangHG,
thank you for the report and the sample project.
This is an intended change, but your case was not thought about.
In 3.4.0
OnlyOnceErrorHandler, the default error handler of every appender, writes the first erroralways. Before it did that only with
log4net.Internal.Debugon. The reason: an appender could stopworking and nobody would see it. See the 3.4.0 changelog, "report the first error of an appender
even when log4net.Internal.Debug is off" (#310).
ecd1b8b
Upgrade note: previously invisible appender errors are now visible, so a misconfigured appender emits one log4net:ERROR line on stderr.XmlConfigurator.ConfigureAndWatchcollects all internal messages and returns them. So an appendererror is now in that list too, not only errors from the config file. Your check "list is not empty"
is therefore stricter than before.
LogLog.EmitInternalMessages = falsedoes not help, it only stops the console output.log4net.Internal.Quiethides every internal error, which you probably do not want.Filtering works. Appender errors come from
OnlyOnceErrorHandler, config errors from another type:The appender in your stack trace is not ours, but our own
EventLogAppendersends the same message.An appender that cannot start is a configuration problem, so its error belongs in that list.
The filter above is the way to separate it from errors in the config file.
Does that solve your problem?
WolfgangHG commentedon Sep 29, 2026
@FreeAndNil Thanks for the clarification. I will implement the suggested workaround.
It is obvious that forwarding a logger initialization error is the correct approach. Previously, the logger would have been disabled silently, which makes it hard to diagnose the missing log.
I will close this issue if one bonus question is answered 😄:
Thinking about the
EventLogAppender, which is not available in .NET6+ applications: the workaround is to use another nuget package, but the source repository of Log4Net.Appenders.NetCore does not even exist any more. The defaultlog4net.Appender.EventLogAppendershould probably work if the log4net Nuget package contains also an assembly for the target frameworknet8.0-windows. But there were probably good reasons for not doing this?If adding another target framework is possible, I could create a new issue to follow this.
FreeAndNil commentedon Sep 29, 2026
@WolfgangHG we are considering to move the Windows only Appenders into their own package (and support for modern .net).
See #267 (#267 (reply in thread))
Please comment on the discussion what you would like to see,
WolfgangHG commentedon Sep 29, 2026
Thanks, Closing this one.