Imageprocessor: Value cannot be null. Parameter name: key (Azure Blob)

Created on 23 Jun 2017  路  8Comments  路  Source: JimBobSquarePants/ImageProcessor

I've recently setup Umbraco to use an Azure Storage Account for storing all media etc. when configuring the image processor to use this I'm seeing some errors.

When referencing an image like this: http://localhost:7989/media/2233/community-answers-v2-975x500.png?anchor=center&mode=crop&width=770&height=385&rnd=131426158890000000 I get the following error:

[ArgumentNullException: Value cannot be null.
Parameter name: key]
   System.Collections.Concurrent.ConcurrentDictionary`2.TryGetValue(TKey key, TValue& value) +12551821
   ImageProcessor.Web.Extensions.InstanceCreationFactory`3.CacheInstanceCreationMethodIfRequired(Type type) +44
   ImageProcessor.Web.Extensions.InstanceCreationFactory`3.CreateInstanceOf(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3) +29
   ImageProcessor.Web.Extensions.TypeInitializationExtensions.GetInstance(Type type, TArg1 argument1, TArg2 argument2, TArg3 argument3) +59
   ImageProcessor.Web.HttpModules.<ProcessImageAsync>d__32.MoveNext() +1636
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar) +71
   System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +380
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

If I remove the query string parameters, the image loads fine. Any pointers?

Most helpful comment

Circled back around to this (eventually!).

The problem was two-fold. The configuration was wrong as per @JimBobSquarePants above, but in addition the currentCache property was not updated (as per @Telaran).

Thanks all.

All 8 comments

Removing the the querystring bypasses ImageProcessor.

You must have configured the ImageProcessor.Web plugin incorrectly.

I'd need to see your configuration and set up to know what was going on. Some version numbers would be nice too.

Here's the configuration:

cache.config

<?xml version="1.0" encoding="utf-8"?>
<caching currentCache="DiskCache">
  <caches>
    <cache name="AzureBlobCache" type="ImageProcessor.Web.Plugins.AzureBlobCache.AzureBlobCache, ImageProcessor.Web.Plugins.AzureBlobCache" maxDays="365">
        <settings>
          <setting key="CachedStorageAccount" value="DefaultEndpointsProtocol=https;AccountName=xxxxxx;AccountKey=yyyyyy;EndpointSuffix=core.windows.net" />
          <setting key="CachedBlobContainer" value="cache" />
          <setting key="UseCachedContainerInUrl" value="true" />
          <setting key="CachedCDNRoot" value="[CdnRootUrl]" />
          <setting key="CachedCDNTimeout" value="1000" />
          <setting key="SourceStorageAccount" value="" />
          <setting key="SourceBlobContainer" value="" />
          <setting key="StreamCachedImage" value="false" />
        </settings>
      </cache>
  </caches>
</caching>

security.config

<?xml version="1.0" encoding="utf-8"?>
<security>
  <services>
    <service name="LocalFileImageService" type="ImageProcessor.Web.Services.LocalFileImageService, ImageProcessor.Web" />
    <service prefix="remote.axd" name="RemoteImageService" type="ImageProcessor.Web.Services.RemoteImageService, ImageProcessor.Web">
      <settings>
        <setting key="MaxBytes" value="4194304" />
        <setting key="Timeout" value="3000" />
        <setting key="Protocol" value="http" />
      </settings>
      <whitelist>
        <add url="http://xxxxxxx.blob.core.windows.net/" />
      </whitelist>
    </service>
    <service prefix="media/" name="CloudImageService" type="ImageProcessor.Web.Services.CloudImageService, ImageProcessor.Web">
      <settings>
        <setting key="Container" value="media" />
        <setting key="MaxBytes" value="8194304" />
        <setting key="Timeout" value="30000" />
        <setting key="Host" value="http://xxxxxxx.blob.core.windows.net/" />
      </settings>
    </service>
  </services>
</security>

FileSystemProviders.config

<?xml version="1.0"?>
<FileSystemProviders>

  <!-- Media -->
  <Provider alias="media" type="Our.Umbraco.FileSystemProviders.Azure.AzureBlobFileSystem, Our.Umbraco.FileSystemProviders.Azure">
    <Parameters>
        <add key="containerName" value="media"/>
        <add key="rootUrl" value="http://xxxxxxxx.blob.core.windows.net/"/>
        <add key="connectionString" value="DefaultEndpointsProtocol=https;AccountName=xxxxxx;AccountKey=yyyyyyyyyy;EndpointSuffix=core.windows.net"/>
        <!--
        Optional configuration value determining the maximum number of days to cache items in the browser.
        Defaults to 365 days.
      -->
        <add key="maxDays" value="365"/>
        <!--
        When true this allows the VirtualPathProvider to use the default "media" route prefix regardless 
        of the container name.
      -->
        <add key="useDefaultRoute" value="true"/>
    </Parameters>
  </Provider>
</FileSystemProviders>

ImageProcessor.dll -> 2.5.4
ImageProcessor.Web.dll -> 4.8.4
ImageProcessor.Web.Plugins.AzureBlobCache.dll -> 1.3.1

I think I followed the guide correctly but let me know if you spot an issue... Thanks for your help :)

Are you using the RemoteImageService? Don't for cloud stuff.

Your CloudImageService config is wrong.

<?xml version="1.0"?>
<security>
  <services>
    <service prefix="media/" name="CloudImageService" type="ImageProcessor.Web.Services.CloudImageService, ImageProcessor.Web">
      <settings>
        <setting key="MaxBytes" value="8194304"/>
        <setting key="Timeout" value="30000"/>
        <setting key="Host" value="http://[myAccountName].blob.core.windows.net/media/"/>
      </settings>
    </service>
  </services>  
</security>

I'm yet to try out your solution but will hopefully get a chance next week - I'm on a few Umbraco training courses this week! Could you reopen this issue?

I have the same issue as you and now started to debug the whole.

1) cache.config
There is a "currentCache" setting on top and have to match the CacheName. So "DiskCache" should be replaced to "AzureBlobCache". After that it will find your cache.

<caching currentCache="DiskCache">

2) security.config
It's still necessary to define the container. So this yours is correct.

security.config without "Container":

I guess there is a small bug on CloudImageService. The CloudImageService does ignore the path.
I'll create a new issue for that topic #635

Nope. Your new issue is incorrect. I suggest learning what the different parts of a URL are.

Circled back around to this (eventually!).

The problem was two-fold. The configuration was wrong as per @JimBobSquarePants above, but in addition the currentCache property was not updated (as per @Telaran).

Thanks all.

Just had the same issue, ultimately the same solution but I wanted to provide a little extra detail to help future confused googlers like myself.

So the exception is "System.ArgumentNullException: Value cannot be null. Parameter name: key", so there's a "key" value that's null. The second thing to notice is that the exception is thrown from ImageProcessor's CacheInstanceCreationMethodIfRequired method, which narrows the issue down to a caching-related "key" value. The actual key it's looking for is in the caching config <setting> elements. In my case, I was doing a config transform incorrectly which had removed the <caching> section completely, so it obviously couldn't find any keys at all.

Also note that you don't HAVE to use the AzureBlobCache, contrary to what everyone keeps saying. DiskCache works fine, just make sure you warm up the whole site first (e.g. in a deployment slot) so nobody has to wait for images to process. And of course if performance is a concern you should be using a CDN anyway.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xumix picture xumix  路  10Comments

rcharb1 picture rcharb1  路  8Comments

Bartmax picture Bartmax  路  8Comments

x2764tech picture x2764tech  路  7Comments

Jogai picture Jogai  路  6Comments