title: Unable to load DLL 'libdl' when using System.Drawing.Common NuGet package on AWS Lambda
body: <p>We have a thumbnail generator lambda function which I'm trying to update to .NET Core 2.0, but I've encountered the following error when using Microsoft's <code>System.Drawing.Common</code> NuGet package:</p>
  
  <blockquote>
    <p>TypeInitializationException</p>
    
    <p>The type initializer for 'Gdip' threw an exception.
    at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, Int32 format, HandleRef scan0, IntPtr&amp; bitmap)
    at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
    at TestFailExample.Function.FunctionHandler(String input, ILambdaContext context) in C:\work\graphics\TestFailExample\Function.cs:line 25
    at lambda_method(Closure , Stream , Stream , LambdaContextInternal )</p>
  </blockquote>
  
  <p>caused by</p>
  
  <blockquote>
    <p>DllNotFoundException</p>
    
    <p>Unable to load DLL 'libdl': The specified module or one of its dependencies could not be found.\n (Exception from HRESULT: 0x8007007E)
    at Interop.Libdl.dlopen(String fileName, Int32 flag)
    at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary()
    at System.Drawing.SafeNativeMethods.Gdip..cctor()</p>
  </blockquote>
  
  <p>I've seen <a href="https://stackoverflow.com/questions/50517769/aws-lambda-function-written-with-net-core-2-0-cannot-load-libdl">this</a> question, but there was no resolution.</p>
  
  <p>The minimum code to reproduce the issue is this:</p>
  
  <pre><code>public string FunctionHandler(string input, ILambdaContext context)
  {
      using (var bmp = new Bitmap(100, 100))
      {
          return bmp.Width.ToString();
      }
  }
  </code></pre>
  
  <p>Simply create a .NET Core 2.0 Lambda function project, add a reference to the <code>System.Drawing.Common</code> NuGet package, and replace the function handler with the above code. Chuck it on AWS and run it to get the error. I've noted that referencing the package doesn't cause a problem until you try to actually use it, but this could be down to compiler optimizations.</p>
  
  <p>I've packaged the MCVE into a project and uploaded it to GitHub <a href="https://github.com/lostllama/aws-lambda-drawing-error-example" rel="noreferrer">here</a> for the sake of simplifying the steps people have to go through to reproduce the issue.</p>
  
  <p>I can see that <code>/lib64/libdl.so.2</code> exists, but <code>/lib64/libdl.so</code> does not. Since symlinking doesn't seem to be possible (read-only file system), I'm not sure how I can resolve this. I've tried using the <code>LD_LIBRARY_PATH</code> environment variable by creating a folder in <code>/tmp</code> and symlinking the file there as the first thing the function does. Unfortunately, it seems to look here for all libraries so the function doesn't run at all. I've also tried setting <code>LD_LIBRARY_PATH</code> to <code>/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/tmp</code> and, although I could now run the function again, this still didn't help and I just get the same Gdip error.</p>
  
  <p>I noted that /var/task/lib is already included in the LD_LIBRARY_PATH, so I tried packaging libdl.so and libgdiplus.so with my function, but this also failed, this time stating that entry point <code>GdiplusStartup</code> wasn't found in <code>libdgiplus.so</code>. These files weren't from an Amazon Linux instance, so I've now tried installing Mono and obtaining them from an Amazon Linux instance. This has not helped.</p>
  
  <p>I've tried with the CoreCompat <a href="https://github.com/CoreCompat/System.Drawing" rel="noreferrer">drawing library</a> but this also reports problems pertaining to <code>libgdiplus.so</code>, even if I try and bundle that with the function.</p>
  
  <p>I've tried since on my own Linux instance and can confirm that <code>System.Drawing.Common</code> works.</p>
  
  <p>Is there some clever solution that will allow me to use <code>System.Drawing.Common</code> on AWS Lambda? Is there another way I can fudge my lambda function to have libdl and work?</p>
  
  <p><strong>Update:</strong></p>
  
  <p>Our latest attempt involved using AWS Lambda Layers and carefully extracting all the packages installed by apt within the Docker Amazon Linux image, and then applying those to their own layer. Still we ultimately came down to the "libdl" issue, so we gave up.</p>
  
  <p>A lot of the issues with libraries people suggested are that they didn't render Japanese text correctly, which is important for us. This seems to be an issue which isn't going to get better on AWS Lambda it didn't help, and ultimately it was easier to rewrite our function in Go than continue using C# for this.</p>
  
  <p>Since the libraries mentioned by the answers below are seemingly suitable for general use - and may indeed support Japanese text now - I've chosen to accept the answer that I'm sure will work on AWS Lambda.</p>