winsw/winsw · error · IOException
File {f} does not follow the pattern provided
Error message
File {f} does not follow the pattern provided What it means
Thrown by RollingLogAppender.GetNextFileNumber during log file rotation when a file matching the glob pattern {baseFileName}.{datePattern}.#*{ext} is found, but the 4 characters after the '#' separator cannot be parsed as an integer. The appender expects a zero-padded sequence number in the #NNNN format to determine the next file number.
Source
Thrown at src/WinSW.Core/LogAppenders.cs:640
else
{
foreach (string? f in files)
{
try
{
string? filenameOnly = Path.GetFileNameWithoutExtension(f);
int hashIndex = filenameOnly.IndexOf('#');
string? lastNumberAsString = filenameOnly.Substring(hashIndex + 1, 4);
if (int.TryParse(lastNumberAsString, out int lastNumber))
{
if (lastNumber > nextFileNumber)
{
nextFileNumber = lastNumber;
}
}
else
{
throw new IOException($"File {f} does not follow the pattern provided");
}
}
catch (Exception e)
{
throw new IOException($"Failed to process file {f} due to error {e.Message}", e);
}
}
if (nextFileNumber == 0)
{
throw new IOException("Cannot roll the file because matching pattern not found");
}
nextFileNumber++;
}
return nextFileNumber;
}View on GitHub (pinned to 1d0ee4a91b)
Solutions
- Remove or rename non-conforming files from the WinSW log directory
- Ensure no other application writes files matching the {baseName}.{date}.#*{ext} glob into the log directory
- If the log directory must be shared, configure a dedicated WinSW log subdirectory
Defensive patterns
Strategy: validation
Validate before calling
// Before rotation, scan the log directory for non-conforming files
string glob = $"{baseFileName}.{now:yyyyMMdd}.#*{ext}";
foreach (var f in Directory.GetFiles(baseDirectory, glob))
{
var name = Path.GetFileNameWithoutExtension(f);
int hash = name.IndexOf('#');
if (hash < 0 || hash + 4 >= name.Length || !int.TryParse(name.Substring(hash + 1, 4), out _))
{
Console.Error.WriteLine($"Non-conforming log file will block rotation: {f}");
}
} Try / catch
try
{
int next = GetNextFileNumber(ext, baseDirectory, baseFileName, now);
}
catch (IOException ex) when (ex.Message.Contains("does not follow the pattern"))
{
eventLogger.WriteEntry($"Skipping rotation due to non-conforming log file: {ex.Message}");
} Prevention
- Keep the WinSW log directory exclusive to WinSW-managed files
- Periodically clean up old or manually-created files in the log directory
- Do not manually create files matching the {baseName}.{date}.#*{ext} glob pattern
When it happens
Trigger: GetNextFileNumber calls Directory.GetFiles with the glob, then for each file extracts filenameOnly.Substring(hashIndex + 1, 4) and runs int.TryParse. If those 4 characters are non-numeric the try-block throws this IOException. This happens when a file matches the glob (e.g., myservice.20240101.#abc.log) but the post-# segment is not a 4-digit number.
Common situations: A user or another process manually creates files in the log directory whose names match the glob but don't follow the #NNNN convention; leftover files from a different logging framework or an older WinSW pattern; a filename where '#' appears in an unexpected position causing the wrong 4 characters to be extracted.
Related errors
- Cannot roll the file because matching pattern not found
- Failed to process file {f} due to error {e.Message}
- Time Based rolling policy is specified but no pattern can be
- Roll-Size-Time Based rolling policy is specified but no patt
- Roll-Size-Time Based rolling policy is specified but autoRol
AI-assisted analysis of winsw/winsw@1d0ee4a91b (2026-08-13).
Data as JSON: /api/errors/16e954b66bc2848d.
Report an issue: GitHub.