Unexpected exit re: Too many open files (File::Error)

Hi

I’m brand new to crystal, and opted to write a Kemal project over the weekend as a learning exercise. It’s a fairly basic app that reads a flurry of inbound JSON post messages (about 40/s) into a nested struct (with include JSON::Serializable at the tops of those, and using ‘property’) and then the struct is pushed into a Deque to a limit of 1000 items. There are other api methods to read from the Deque to process the data and return results. I’ve compiled it with just ‘crystal build’ and run the exe on MacOs. Generally it works well. It consumes around 300MB RAM and peaks at 56% CPU usage. I’ve noticed it only uses 1 thread.

However I noticed it randomly crashed out with a ‘Too many open files (File::Error)’ which is a bit strange for me, as I’m not doing any file operations that I’m aware of.

I’ve turned off Kemal logging via (which I hope is right)

Kemal.config.logging = false
Log.setup(:error)  # Only show actual errors

Here’s the full error dump. I’d be grateful for any pointers to help me understand what I should do to pinpoint this.

Unable to load dwarf information: Error opening file with mode 'r': '/Users/michael/Documents/tests/myapp': Too many open files (File::Error)
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::unwind:Array(Pointer(Void))'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack#initialize:Array(Pointer(Void))'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::new:Exception::CallStack'
  from /Users/michael/Documents/tests/myapp in 'raise<File::Error+>:NoReturn'
  from /Users/michael/Documents/tests/myapp in 'Crystal::System::File::open<String, String, File::Permissions, Nil>:Tuple(Int32, Bool)'
  from /Users/michael/Documents/tests/myapp in 'File::new<String, String, File::Permissions, Nil, Nil, Nil>:File'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::read_dwarf_sections:Nil'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::load_debug_info_impl:Nil'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::load_debug_info:Nil'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::decode_line_number<UInt64>:Tuple(String, Int32, Int32)'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::decode_backtrace_frame<Pointer(Void), Bool>:(String | Nil)'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack#decode_backtrace:Array(String)'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack#printable_backtrace:Array(String)'
  from /Users/michael/Documents/tests/myapp in 'Exception+@Exception#backtrace?:(Array(String) | Nil)'
  from /Users/michael/Documents/tests/myapp in 'Exception+@Exception#inspect_with_backtrace<IO::Memory>:Nil'
  from /Users/michael/Documents/tests/myapp in 'Crystal::buffered_message:exception:backtrace<String, Exception+, Nil>:IO::Memory'
  from /Users/michael/Documents/tests/myapp in 'Crystal::print_buffered:exception:to<String, Exception+, IO::FileDescriptor>:Nil'
  from /Users/michael/Documents/tests/myapp in 'Fiber#run:Nil'
  from /Users/michael/Documents/tests/myapp in '~proc2Proc(Fiber, Nil)@/opt/homebrew/Cellar/crystal/1.17.1/share/crystal/src/fiber.cr:105'
Unhandled exception in spawn: Error opening file with mode 'r': '/etc/localtime': Too many open files (File::Error)
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::unwind:Array(Pointer(Void))'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack#initialize:Array(Pointer(Void))'
  from /Users/michael/Documents/tests/myapp in 'Exception::CallStack::new:Exception::CallStack'
  from /Users/michael/Documents/tests/myapp in 'raise<File::Error+>:NoReturn'
  from /Users/michael/Documents/tests/myapp in 'Crystal::System::File::%

BTW I’m using a Deque as I want to limit the number of captured JSON messages into the struct to 1000, and at capacity, I’m unshifting and then pushing the new one in - is that the best way to have this kind of buffer?

Thanks.

To start, I would be sure to build via crystal build --release and see if that makes a difference. Otherwise, is your app doing anything with files (Time specifically given the trace points to /etc/localtime)?

I don’t think release mode should have any effect on open files.

The error originating at /etc/localtime does not point to the origin of problem. It’s just a symptom (ref Using a logger causes infinite spam logs when file descriptor limit is reached in `HTTP::Server` · Issue #15862 · crystal-lang/crystal · GitHub).

1 Like

The default limit for open file descriptors on macOS is fairly low at just 256 (you can check with ulimit -n).
If your program keeps a number of sockets open for a while, it might just happen that it reaches the limit very quickly.

There might be something in your code that encourages that, but it could be entirely genuine behaviour.

You can easily increase the limit though to an amount that’s more appropriate for your workload.

Thanks for the replies.

I’m not doing anything with files. I am using Time, but for things like determining runtimes via

start = Time.monotonic
...
elapsed = = Time.monotonic - start_time

and putting a string version into the JSON returned from the API.

I’m also doing some date processing like:

utc_session_datetime = Time.parse(@created_on, "%Y-%m-%dT%H:%M:%S.%N", Time::Location.load("UTC"))
utc_session_datetime.in Time::Location.load("Australia/Brisbane")

but not opening/closing local files. So is Time treated like a file somehow on Mac?

About ulimit -n I get 256 for that.

How about checking what files the kemal appis opening?

lsof -p $(pgrep myapp)

Here’s the output from the sample memo app I had Claude Sonnet write for me the other day.

COMMAND  PID   USER   FD     TYPE             DEVICE  SIZE/OFF                NODE NAME
memo    4439 kojix2  cwd      DIR               1,15       480           127970661 /Users/kojix2/Crystal/memo.cr
memo    4439 kojix2  txt      REG               1,15   2379048           129576877 /Users/kojix2/Crystal/memo.cr/bin/memo
memo    4439 kojix2  txt      REG               1,15     67576           130417442 /Library/Preferences/Logging/.plist-cache.lQZxc3e4
memo    4439 kojix2  txt      REG               1,15     32768           127973618 /Users/kojix2/Library/Application Support/Memo/memo.db-shm
memo    4439 kojix2  txt      REG               1,15   2289328 1152921500312524413 /usr/lib/dyld
memo    4439 kojix2  txt      REG               1,15    887360           120923539 /opt/homebrew/Cellar/openssl@3/3.5.2/lib/libssl.3.dylib
memo    4439 kojix2  txt      REG               1,15    573296           125253932 /opt/homebrew/Cellar/pcre2/10.46/lib/libpcre2-8.0.dylib
memo    4439 kojix2  txt      REG               1,15    207328            56607082 /opt/homebrew/Cellar/bdw-gc/8.2.8/lib/libgc.1.5.4.dylib
memo    4439 kojix2  txt      REG               1,15    294010           130417984 /private/var/db/analyticsd/events.allowlist
memo    4439 kojix2  txt      REG               1,15   4718480           120923530 /opt/homebrew/Cellar/openssl@3/3.5.2/lib/libcrypto.3.dylib
memo    4439 kojix2  txt      REG               1,15  33979312 1152921500312534923 /usr/share/icu/icudt76l.dat
memo    4439 kojix2  txt      REG               1,15    235024            95982198 /private/var/db/timezone/tz/2025b.1.0/icutz/icutz44l.dat
memo    4439 kojix2  txt      REG               1,15    139240 1152921500312087952 /System/Library/CoreServices/SystemAppearance.bundle/Contents/Resources/SystemAppearance.car
memo    4439 kojix2  txt      REG               1,15       110 1152921500312088251 /System/Library/CoreServices/SystemVersion.bundle/English.lproj/SystemVersion.strings
memo    4439 kojix2  txt      REG               1,15   7919192 1152921500312087913 /System/Library/CoreServices/SystemAppearance.bundle/Contents/Resources/Aqua.car
memo    4439 kojix2  txt      REG               1,15   2976648 1152921500312087941 /System/Library/CoreServices/SystemAppearance.bundle/Contents/Resources/FauxVibrantLight.car
memo    4439 kojix2  txt      REG               1,15   6222152 1152921500312087966 /System/Library/CoreServices/SystemAppearance.bundle/Contents/Resources/VibrantLight.car
memo    4439 kojix2  txt      REG               1,15   1493020 1152921500312193368 /System/Library/Keyboard Layouts/AppleKeyboardLayouts.bundle/Contents/Resources/AppleKeyboardLayouts-L.dat
memo    4439 kojix2  txt      REG               1,15  12812288           130432938 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/0/com.apple.LaunchServices.dv/com.apple.LaunchServices-6291460-v2.csstore
memo    4439 kojix2  txt      REG               1,15    143672           130420785 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.IntlDataCache.le.kbdx
memo    4439 kojix2  txt      REG               1,15    242340 1152921500312193370 /System/Library/Keyboard Layouts/AppleKeyboardLayouts.bundle/Contents/Resources/InfoPlist.loctable
memo    4439 kojix2  txt      REG               1,15    248480 1152921500312524429 /usr/lib/libobjc-trampolines.dylib
memo    4439 kojix2  txt      REG               1,15   8330740 1152921500312124572 /System/Library/Fonts/SFNS.ttf
memo    4439 kojix2  txt      REG               1,15   1516176 1152921500312111863 /System/Library/Extensions/AGXMetalG14G.bundle/Contents/Resources/ds.g14g
memo    4439 kojix2  txt      REG               1,15        89            60363296 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.WebPrivacy/RESTRICTED_OPENER_DOMAINS.wplist
memo    4439 kojix2  txt      REG               1,15      1340 1152921500312302921 /System/Library/PrivateFrameworks/MarkupUI.framework/PlugIns/Markup.appex/Contents/Resources/InfoPlist.loctable
memo    4439 kojix2  txt      REG               1,15     60672 1152921500312126493 /System/Library/Frameworks/AppKit.framework/Versions/C/Resources/Common.loctable
memo    4439 kojix2  txt      REG               1,15       706 1152921500312326977 /System/Library/PrivateFrameworks/ShareKit.framework/Versions/A/PlugIns/ShareSheetUI.appex/Contents/Resources/InfoPlist.loctable
memo    4439 kojix2  txt      REG               1,15       204            60245822 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.WebPrivacy/STORAGE_ACCESS_USER_AGENT_STRING_QUIRKS.wplist
memo    4439 kojix2  txt      REG               1,15       450           109386010 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.WebPrivacy/QUERY_PARAM.wplist
memo    4439 kojix2  txt      REG               1,15   1263216 1152921500312115613 /System/Library/Extensions/AppleMetalOpenGLRenderer.bundle/Contents/MacOS/AppleMetalOpenGLRenderer
memo    4439 kojix2  txt      REG               1,15    111246 1152921500312327215 /System/Library/PrivateFrameworks/ShareKit.framework/Versions/A/Resources/ShareKit.loctable
memo    4439 kojix2  txt      REG               1,15     29800 1152921500312259741 /System/Library/PrivateFrameworks/CoreUI.framework/Versions/A/Resources/DesignLibrary-macOS.bundle/Contents/Resources/macOSRepositories/LightStandard.car
memo    4439 kojix2  txt      REG               1,15    363228 1152921500312133725 /System/Library/Frameworks/CoreImage.framework/Versions/A/Resources/Filters.loctable
memo    4439 kojix2  txt      REG               1,15   2369592 1152921500312124498 /System/Library/Fonts/Helvetica.ttc
memo    4439 kojix2  txt      REG               1,15    209319 1152921500312133730 /System/Library/Frameworks/CoreImage.framework/Versions/A/Resources/Keys.loctable
memo    4439 kojix2  txt      REG               1,15       862            42051981 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.WebPrivacy/ALLOWED_QUERY_PARAM.wplist
memo    4439 kojix2  txt      REG               1,15       339            60245811 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.WebPrivacy/STORAGE_ACCESS_PROMPT_QUIRKS.wplist
memo    4439 kojix2  txt      REG               1,15     38134 1152921500312126577 /System/Library/Frameworks/AppKit.framework/Versions/C/Resources/Menus.loctable
memo    4439 kojix2  txt      REG               1,15   1153157 1152921500312130851 /System/Library/Frameworks/CFNetwork.framework/Versions/A/Resources/DafsaData.bin
memo    4439 kojix2  txt      REG               1,15    227371            36237742 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.Safari.SafeBrowsing/Google/malware,osx,url_expression
memo    4439 kojix2  txt      REG               1,15  19908912 1152921500312111854 /System/Library/Extensions/AGXMetalG14G.bundle/Contents/MacOS/AGXMetalG14G
memo    4439 kojix2  txt      REG               1,15   3497641 1152921500312133723 /System/Library/Frameworks/CoreImage.framework/Versions/A/Resources/Descriptions.loctable
memo    4439 kojix2  txt      REG               1,15   1519323            36237792 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.Safari.SafeBrowsing/Google/unwanted_software,osx,url_expression
memo    4439 kojix2  txt      REG               1,15  24031987            36237744 /private/var/folders/hd/sgd9p6692c71k92cm4c76vth0000gn/C/com.apple.Safari.SafeBrowsing/Google/social_engineering,osx,url_expression
memo    4439 kojix2  txt      REG               1,15 144496840 1152921500312322465 /System/Library/PrivateFrameworks/SFSymbols.framework/Versions/A/Resources/CoreGlyphs.bundle/Contents/Resources/Assets.car
memo    4439 kojix2    0u     CHR               16,1  0t308167                 703 /dev/ttys001
memo    4439 kojix2    1u     CHR               16,1  0t308167                 703 /dev/ttys001
memo    4439 kojix2    2u     CHR               16,1  0t308167                 703 /dev/ttys001
memo    4439 kojix2    3u     CHR               16,1     0t169                 703 /dev/ttys001
memo    4439 kojix2    4u     CHR               16,1       0t0                 703 /dev/ttys001
memo    4439 kojix2    5u  KQUEUE                                                  count=1, state=0x8
memo    4439 kojix2    6u  KQUEUE                                                  count=0, state=0xa
memo    4439 kojix2    7u  KQUEUE                                                  count=0, state=0xa
memo    4439 kojix2    8u  KQUEUE                                                  count=0, state=0xa
memo    4439 kojix2    9     PIPE 0x216a0109eb03aef6     16384                     ->0xaa931dd80ba9780b
memo    4439 kojix2   10     PIPE 0xaa931dd80ba9780b     16384                     ->0x216a0109eb03aef6
memo    4439 kojix2   11u     REG               1,15     16384           128396787 /Users/kojix2/Library/Application Support/Memo/memo.db
memo    4439 kojix2   12u     REG               1,15         0           128396789 /Users/kojix2/Library/Application Support/Memo/memo.db-wal
memo    4439 kojix2   13u     REG               1,15     32768           127973618 /Users/kojix2/Library/Application Support/Memo/memo.db-shm
memo    4439 kojix2   14u   systm 0xc15d25ba36197f25       0t0                     [ctl com.apple.netsrc id 7 unit 14]
memo    4439 kojix2   15u    unix 0x92bdeff85f3888b9       0t0                     ->0x774a85c3a0e7a7de
memo    4439 kojix2   16u    unix 0x8ef897811722f365       0t0                     ->0xcc3de3e44d6b838e
memo    4439 kojix2   17r     REG               1,15    358712 1152921500312115621 /System/Library/Extensions/AppleMetalOpenGLRenderer.bundle/Contents/Resources/default.metallib
memo    4439 kojix2   18u    IPv4 0x5cff408d2df59e59       0t0                 TCP *:49491 (LISTEN)
memo    4439 kojix2   19r     REG               1,15     34984 1152921500312115619 /System/Library/Extensions/AppleMetalOpenGLRenderer.bundle/Contents/Resources/PixelConverter.metallib
1 Like

thanks for the suggestion @kojix2 . I get the following output:

michael@Mac-mini ~ % lsof -p $(pgrep myapp)
COMMAND   PID    USER   FD     TYPE             DEVICE SIZE/OFF                NODE NAME
myapp 4502 michael  cwd      DIR               1,14      448            88028973 /Users/michael/Documents/tests/myapp
myapp 4502 michael  txt      REG               1,14  2063845            89514698 /Users/michael/Documents/tests/myapp/myapp
myapp 4502 michael  txt      REG               1,14   887360             3712053 /opt/homebrew/Cellar/openssl@3/3.5.1/lib/libssl.3.dylib
myapp 4502 michael  txt      REG               1,14  2289328 1152921500312524246 /usr/lib/dyld
myapp 4502 michael  txt      REG               1,14   580272              509223 /opt/homebrew/Cellar/pcre2/10.45/lib/libpcre2-8.0.dylib
myapp 4502 michael  txt      REG               1,14   207312             3704215 /opt/homebrew/Cellar/bdw-gc/8.2.8/lib/libgc.1.5.4.dylib
myapp 4502 michael  txt      REG               1,14  4718400             3712050 /opt/homebrew/Cellar/openssl@3/3.5.1/lib/libcrypto.3.dylib
myapp 4502 michael    0u     CHR               16,5  0t15618                 951 /dev/ttys005
myapp 4502 michael    1u     CHR               16,5  0t15618                 951 /dev/ttys005
myapp 4502 michael    2u     CHR               16,5  0t15618                 951 /dev/ttys005
myapp 4502 michael    3u     CHR               16,5      0t0                 951 /dev/ttys005
myapp 4502 michael    4u     CHR               16,5      0t0                 951 /dev/ttys005
myapp 4502 michael    5u  KQUEUE                                                 count=0, state=0xa
myapp 4502 michael    6     PIPE 0x369ba5ef5ffa2621    16384                     ->0x481736a0a789fa9
myapp 4502 michael    7     PIPE  0x481736a0a789fa9    16384                     ->0x369ba5ef5ffa2621
myapp 4502 michael    8u    IPv4 0x4743981a6847af5e      0t0                 TCP *:hbci (LISTEN)
myapp 4502 michael    9u    IPv4  0x46415d4dbd98294      0t0                 TCP localhost:hbci->localhost:62700 (ESTABLISHED)

I’m not sure how to review this to help me isolate the issue.

BTW I reran the app after the last failure, and it’s run for almost a day before it crashed out with the same issue, so I’ve recompiled with the –-release flag and rerunning again now to see how it goes.

1 Like

This is a very old-school method, but you could try monitoring the number of open files with a simple shell script like this. Using watch or tmux might make it even easier.

PID=4439
while true; do
  printf "%s\t%s\n" "$(date '+%F %T')" "$(lsof -p $PID 2>/dev/null | wc -l)"
  sleep 5
done

If the number keeps increasing over time, that might be the cause.

Thanks. I had noticed a similar suggested via chatgpt, so I’m now running this

while true; do
  lsof -p $(pgrep myapp) | wc -l
  sleep 1
done

and similarly for lsof -p $(pgrep myapp) -a -i and so far, it’s ok. I’ve been running it for about 15 mins, and the first count is going up to 20 but always coming back down to the starting value of 17. Sockets at most appears to be 3 events:

myapp 4502 michael    8u  IPv4 0x4743981a6847af5e      0t0  TCP *:hbci (LISTEN)
myapp 4502 michael    9u  IPv4 0x879d1ea794ec847e      0t0  TCP localhost:hbci->localhost:61435 (ESTABLISHED)
myapp 4502 michael   10u  IPv4 0x8a08ed69265f36a1      0t0  TCP localhost:hbci->localhost:61439 (ESTABLISHED)

checking on Claude based on the lsof output, it suggests:

The issue is clear from your lsof output - you have file descriptor leaks, specifically with TTY (terminal) file descriptors. Notice these lines:

myapp 4502 michael 3u CHR 16,5 0t0 951 /dev/ttys005

myapp 4502 michael 4u CHR 16,5 0t0 951 /dev/ttys005

File descriptors 3 and 4 are duplicates of your terminal that shouldn’t normally be open. This suggests your app is leaking file descriptors somewhere, likely through:

Common Causes in Crystal/Kemal Apps:

  1. Spawned processes without proper cleanup - If you’re using Process.run or spawning any subprocesses

  2. HTTP client connections not being closed - Using HTTP::Client without proper cleanup

  3. WebSocket connections - Not properly closing WebSocket connections

  4. Database connections - Connection pool exhaustion (though you said you’re not using files)

  5. Signal handlers or process pipes - The PIPE file descriptors (6, 7) are normal, but could accumulate

however I’m not doing any of those things listed. So not sure..

I will leave the looping checks run overnight to see what comes of it.

Perhaps ulimit increase is needed, but I think not much is happening with this app.. mainly one inbound connection to feed in data, and once a minute a client calls some APIs within the code to fetch some data out.

1 Like

btw looking at today’s crash error, it’s largely the same as last time, except this (last) part is slightly different (re File::open and Time::load_localtime):

  from /Users/michael/Documents/tests/myapp/myapp in '~proc2Proc(Fiber, Nil)@/opt/homebrew/Cellar/crystal/1.17.1/share/crystal/src/fiber.cr:105'
Unhandled exception in spawn: Error opening file with mode 'r': '/etc/localtime': Too many open files (File::Error)
  from /Users/michael/Documents/tests/myapp/myapp in 'Exception::CallStack::unwind:Array(Pointer(Void))'
  from /Users/michael/Documents/tests/myapp/myapp in 'Exception::CallStack#initialize:Array(Pointer(Void))'
  from /Users/michael/Documents/tests/myapp/myapp in 'Exception::CallStack::new:Exception::CallStack'
  from /Users/michael/Documents/tests/myapp/myapp in 'raise<File::Error+>:NoReturn'
  from /Users/michael/Documents/tests/myapp/myapp in 'Crystal::System::File::open<String, String, File::Permissions, Nil>:Tuple(Int32, Bool)'
  from /Users/michael/Documents/tests/myapp/myapp in 'File::new<String, String, File::Permissions, Nil, Nil, Nil>:File'
  from /Users/michael/Documents/tests/myapp/myapp in 'Crystal::System::Time::load_localtime:(Time::Location+ | Nil)'
  from /Users/michael/Documents/tests/myapp/myapp in 'Time::Location::load%

I’m confused about why there’s a reference to File::open and does it appear that my use of time zone conversion could be an issue? I’m wondering if I should comment-out all my time-related code to see if this clears up the issue?

The stack trace shows Crystal trying to open /etc/localtime to resolve the local timezone.
On Linux and macOS, timezones are files under /usr/share/zoneinfo, and /etc/localtime is a symlink to one of them.

ls -l /etc/localtime
ls /usr/share/zoneinfo
file /usr/share/zoneinfo/Australia/Brisbane
zdump /usr/share/zoneinfo/Australia/Brisbane
zdump /usr/share/zoneinfo/NZ
1 Like

ご丁寧な説明を誠にありがとうございます。

Thanks so much for your kind explanation about that. So this is where the file reference is coming from!

1 Like

For me, this is the output:

╰──➤ $ ls -l /etc/localtime
lrwxrwxrwx - root 1 year /etc/localtime → /usr/share/zoneinfo/Asia/Shanghai

Maybe your’s /etc/localtime is references to it self? e.g. /etc/localtime → /etc/localtime, this will cause the deed loop.

1 Like

Thanks for your suggestion. I tried the ls command you suggested, and my result is similar to yours (no loop).

I still feel this is still a bit of a head-scratcher to me (programming on Mac is still new, after coming from Windows). So calling Time::Location.load("UTC") is essentially opening a file, and this seems to be leading to the need to called the ulimit which upon increasing does seem to solve my problem, on the other hand I think I’m also suppressing logs (which is where I display the results of the time functions I showed above).

If the file-opening situation is true, I wonder why the crash - is somehow the file not being closed? I don’t really understand the need for the ulimit increase. I understand my crash issue is not a crystal matter, but rather linked to the way MacOS works and ulimit.

Thanks very much for all your help.

Please refer to my previous comment. Investigating /etc/localtime doesn’t lead anywhere. The error message mentioning /etc/localtime does not describe the source of the error. This is just a symptom. The linked issue discussion explains this in more detail.

As mentioned there, you can add Time::Location.local = Time::Location::UTC to your code (or run with TZ=UTC) in order to suppress this secondary error.

I think he means that /etc/localtime was just the final trigger. You should check where the file descriptors are actually leaking. That’s probably the next step to figure this out.

ok thanks - so I’ll try to monitor the program for file descriptors overflow, and try to work out what’s going on.