diff --git a/CHANGELOG.md b/CHANGELOG.md
index 283c8880f0c16cacafc258e6bca603c17d806384..954678f09fe71926ceb95cca4db4ffd1e2883ab8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ Note that since we don't clearly distinguish between a public and private interf
 ## [Unreleased]
 
 - Fix VolumeServer/query CLI
+- Support automatic iso-value adjustment for VolumeServer data in ``Viewer.loadVolumeFromUrl``
 
 ## [v3.0.0] - 2022-01-23
 
diff --git a/src/apps/viewer/app.ts b/src/apps/viewer/app.ts
index b399d04bc9f6570004484e9652c05244a8d1f20c..af6afd97b418dca8dfa28700a82a40b53c80296a 100644
--- a/src/apps/viewer/app.ts
+++ b/src/apps/viewer/app.ts
@@ -17,6 +17,7 @@ import { ModelExport } from '../../extensions/model-export';
 import { Mp4Export } from '../../extensions/mp4-export';
 import { PDBeStructureQualityReport } from '../../extensions/pdbe';
 import { RCSBAssemblySymmetry, RCSBValidationReport } from '../../extensions/rcsb';
+import { Volume } from '../../mol-model/volume';
 import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure';
 import { DownloadDensity } from '../../mol-plugin-state/actions/volume';
 import { PresetTrajectoryHierarchy } from '../../mol-plugin-state/builder/structure/hierarchy-preset';
@@ -366,11 +367,13 @@ export class Viewer {
 
             const repr = plugin.build();
             for (const iso of isovalues) {
+                const volume: StateObjectSelector<PluginStateObject.Volume.Data> = parsed.volumes?.[iso.volumeIndex ?? 0] ?? parsed.volume;
+                const volumeData = volume.cell!.obj!.data;
                 repr
-                    .to(parsed.volumes?.[iso.volumeIndex ?? 0] ?? parsed.volume)
+                    .to(volume)
                     .apply(StateTransforms.Representation.VolumeRepresentation3D, createVolumeRepresentationParams(this.plugin, firstVolume.data!, {
                         type: 'isosurface',
-                        typeParams: { alpha: iso.alpha ?? 1, isoValue: iso.type === 'absolute' ? { kind: 'absolute', absoluteValue: iso.value } : { kind: 'relative', relativeValue: iso.value } },
+                        typeParams: { alpha: iso.alpha ?? 1, isoValue: Volume.adjustedIsoValue(volumeData, iso.value, iso.type) },
                         color: 'uniform',
                         colorParams: { value: iso.color }
                     }));
diff --git a/src/mol-model/volume/volume.ts b/src/mol-model/volume/volume.ts
index 280a32d7e26e9f2a3f455b3c77e84677b488ebf5..8a322563ae06817f174312c55f413357baded5a1 100644
--- a/src/mol-model/volume/volume.ts
+++ b/src/mol-model/volume/volume.ts
@@ -15,6 +15,7 @@ import { ModelFormat } from '../../mol-model-formats/format';
 import { CustomProperties } from '../custom-property';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { toPrecision } from '../../mol-util/number';
+import { DscifFormat } from '../../mol-model-formats/volume/density-server';
 
 export interface Volume {
     readonly label?: string
@@ -84,6 +85,23 @@ export namespace Volume {
         }
     }
 
+    // Converts iso value to relative if using downsample VolumeServer data
+    export function adjustedIsoValue(volume: Volume, value: number, kind: 'absolute' | 'relative') {
+        if (kind === 'relative') return IsoValue.relative(value);
+
+        const absolute = IsoValue.absolute(value);
+        if (DscifFormat.is(volume.sourceData)) {
+            const stats = {
+                min: volume.sourceData.data.volume_data_3d_info.min_source.value(0),
+                max: volume.sourceData.data.volume_data_3d_info.max_source.value(0),
+                mean: volume.sourceData.data.volume_data_3d_info.mean_source.value(0),
+                sigma: volume.sourceData.data.volume_data_3d_info.sigma_source.value(0),
+            };
+            return Volume.IsoValue.toRelative(absolute, stats);
+        }
+        return absolute;
+    }
+
     const defaultStats: Grid['stats'] = { min: -1, max: 1, mean: 0, sigma: 0.1 };
     export function createIsoValueParam(defaultValue: Volume.IsoValue, stats?: Grid['stats']) {
         const sts = stats || defaultStats;
diff --git a/src/mol-plugin-state/formats/volume.ts b/src/mol-plugin-state/formats/volume.ts
index d3701364f2018e11e37cabf0576a52f0c88850b5..f2c527738c53323a48191cb2906ffa764e67e247 100644
--- a/src/mol-plugin-state/formats/volume.ts
+++ b/src/mol-plugin-state/formats/volume.ts
@@ -18,7 +18,6 @@ import { objectForEach } from '../../mol-util/object';
 import { RecommendedIsoValue } from '../../mol-model-formats/volume/property';
 import { getContourLevelEmdb } from '../../mol-plugin/behavior/dynamic/volume-streaming/util';
 import { Task } from '../../mol-task';
-import { DscifFormat } from '../../mol-model-formats/volume/density-server';
 
 export const VolumeFormatCategory = 'Volume';
 type Params = { entryId?: string };
@@ -42,19 +41,9 @@ async function tryObtainRecommendedIsoValue(plugin: PluginContext, volume?: Volu
 function tryGetRecomendedIsoValue(volume: Volume) {
     const recommendedIsoValue = RecommendedIsoValue.Provider.get(volume);
     if (!recommendedIsoValue) return;
-
     if (recommendedIsoValue.kind === 'relative') return recommendedIsoValue;
 
-    let stats = volume.grid.stats;
-    if (DscifFormat.is(volume.sourceData)) {
-        stats = {
-            min: volume.sourceData.data.volume_data_3d_info.min_source.value(0),
-            max: volume.sourceData.data.volume_data_3d_info.max_source.value(0),
-            mean: volume.sourceData.data.volume_data_3d_info.mean_source.value(0),
-            sigma: volume.sourceData.data.volume_data_3d_info.sigma_source.value(0),
-        };
-    }
-    return Volume.IsoValue.toRelative(recommendedIsoValue, stats);
+    return Volume.adjustedIsoValue(volume, recommendedIsoValue.absoluteValue, 'absolute');
 }
 
 async function defaultVisuals(plugin: PluginContext, data: { volume: StateObjectSelector<PluginStateObject.Volume.Data> }) {