diff --git a/src/apps/basic-wrapper/index.html b/src/apps/basic-wrapper/index.html
index 6c9f2d9d571045339824a9f9cd10a8d2a207ab39..cb24e98ba931d901fc1b957c99c0328ba08a7433 100644
--- a/src/apps/basic-wrapper/index.html
+++ b/src/apps/basic-wrapper/index.html
@@ -109,6 +109,7 @@
 
             addControl('Static Superposition', () => BasicMolStarWrapper.tests.staticSuperposition());
             addControl('Dynamic Superposition', () => BasicMolStarWrapper.tests.dynamicSuperposition());
+            addControl('Validation Tooltip', () => BasicMolStarWrapper.tests.toggleValidationTooltip());
 
             ////////////////////////////////////////////////////////
 
diff --git a/src/apps/basic-wrapper/index.ts b/src/apps/basic-wrapper/index.ts
index 4629abcf45c4a15cc44e56979a266eb4549cdacc..c722e95e43d234e4edc8150f7088ac811d3a709e 100644
--- a/src/apps/basic-wrapper/index.ts
+++ b/src/apps/basic-wrapper/index.ts
@@ -17,6 +17,7 @@ import { StateBuilder, StateTransform } from '../../mol-state';
 import { StripedResidues } from './coloring';
 // import { BasicWrapperControls } from './controls';
 import { StaticSuperpositionTestData, buildStaticSuperposition, dynamicSuperpositionTest } from './superposition';
+import { PDBeStructureQualityReport } from '../../mol-plugin/behavior/dynamic/custom-props';
 require('mol-plugin/skin/light.scss')
 
 type SupportedFormats = 'cif' | 'pdb'
@@ -152,6 +153,11 @@ class BasicWrapper {
         dynamicSuperposition: async () => {
             await PluginCommands.State.RemoveObject.dispatch(this.plugin, { state: this.plugin.state.dataState, ref: StateTransform.RootRef });
             await dynamicSuperpositionTest(this.plugin, ['1tqn', '2hhb', '4hhb'], 'HEM');
+        },
+        toggleValidationTooltip: async () => {
+            const state = this.plugin.state.behaviorState;
+            const tree = state.build().to(PDBeStructureQualityReport.id).update(PDBeStructureQualityReport, p => ({ ...p, showTooltip: !p.showTooltip }));
+            await PluginCommands.State.Update.dispatch(this.plugin, { state, tree });
         }
     }
 }
diff --git a/src/examples/proteopedia-wrapper/annotation.ts b/src/examples/proteopedia-wrapper/annotation.ts
index d628f628a21cb6354ec0588459e66097c238ee93..1d88eae3f7b412a40cf672a70c44f05d3fc0ebc8 100644
--- a/src/examples/proteopedia-wrapper/annotation.ts
+++ b/src/examples/proteopedia-wrapper/annotation.ts
@@ -27,7 +27,7 @@ export const EvolutionaryConservation = CustomElementProperty.create<number>({
     name: 'proteopedia-wrapper-evolutionary-conservation',
     display: 'Evolutionary Conservation',
     async getData(model: Model) {
-        const id = model.label.toLowerCase();
+        const id = model.entryId.toLowerCase();
         const req = await fetch(`https://proteopedia.org/cgi-bin/cnsrf?${id}`);
         const json = await req.json();
         const annotations = (json && json.residueAnnotations) || [];
diff --git a/src/examples/proteopedia-wrapper/helpers.ts b/src/examples/proteopedia-wrapper/helpers.ts
index d8d4f26101b9635cf14936e4657c71565780cc30..d376596d3157a6b9bda160bf5bb9346443dc69ae 100644
--- a/src/examples/proteopedia-wrapper/helpers.ts
+++ b/src/examples/proteopedia-wrapper/helpers.ts
@@ -18,9 +18,9 @@ export interface ModelInfo {
 
 export namespace ModelInfo {
     async function getPreferredAssembly(ctx: PluginContext, model: Model) {
-        if (model.label.length <= 3) return void 0;
+        if (model.entryId.length <= 3) return void 0;
         try {
-            const id = model.label.toLowerCase();
+            const id = model.entryId.toLowerCase();
             const src = await ctx.runTask(ctx.fetch({ url: `https://www.ebi.ac.uk/pdbe/api/pdb/entry/summary/${id}` })) as string;
             const json = JSON.parse(src);
             const data = json && json[id];
diff --git a/src/mol-model-formats/structure/mmcif/parser.ts b/src/mol-model-formats/structure/mmcif/parser.ts
index 6d464764438da589ec664cc398e15c8b4c100438..2ec01ddd4cc1403460242424c413226fdc476851 100644
--- a/src/mol-model-formats/structure/mmcif/parser.ts
+++ b/src/mol-model-formats/structure/mmcif/parser.ts
@@ -217,6 +217,7 @@ function createStandardModel(format: mmCIF_Format, atom_site: AtomSite, sourceIn
 
     return {
         id: UUID.create22(),
+        entryId: entry,
         label: label.join(' | '),
         entry,
         sourceData: format,
@@ -253,6 +254,7 @@ function createModelIHM(format: mmCIF_Format, data: IHMData, formatData: FormatD
 
     return {
         id: UUID.create22(),
+        entryId: entry,
         label: label.join(' | '),
         entry,
         sourceData: format,
diff --git a/src/mol-model-props/pdbe/structure-quality-report.ts b/src/mol-model-props/pdbe/structure-quality-report.ts
index ada52bbb55e464dd78c8a22338f916f3e6ad5d58..7cc742b6661a6cd6bd0762d962fba7573adf5908 100644
--- a/src/mol-model-props/pdbe/structure-quality-report.ts
+++ b/src/mol-model-props/pdbe/structure-quality-report.ts
@@ -98,7 +98,7 @@ export namespace StructureQualityReport {
             {
                 const url = mapUrl(model);
                 const dataStr = await fetch({ url }).runInContext(ctx) as string;
-                const data = JSON.parse(dataStr)[model.label.toLowerCase()];
+                const data = JSON.parse(dataStr)[model.entryId.toLowerCase()];
                 if (!data) return false;
                 info = PropertyWrapper.createInfo();
                 issueMap = createIssueMapFromJson(model, data);
diff --git a/src/mol-model-props/rcsb/assembly-symmetry.ts b/src/mol-model-props/rcsb/assembly-symmetry.ts
index bdf36072cb34acacc21b0eb9a5da5ff30c894363..d87065908d586257784f9f29439ffe975144661c 100644
--- a/src/mol-model-props/rcsb/assembly-symmetry.ts
+++ b/src/mol-model-props/rcsb/assembly-symmetry.ts
@@ -264,8 +264,8 @@ export namespace AssemblySymmetry {
             db = createDatabaseFromCif(model)
         } else {
             let result: AssemblySymmetryGraphQL.Query
-            console.log('model.label.toLowerCase()', model.label.toLowerCase())
-            const variables: AssemblySymmetryGraphQL.Variables = { pdbId: model.label.toLowerCase() };
+            console.log('model.entryId.toLowerCase()', model.entryId.toLowerCase())
+            const variables: AssemblySymmetryGraphQL.Variables = { pdbId: model.entryId.toLowerCase() };
             try {
                 console.log('foo', client)
                 result = await client.request<AssemblySymmetryGraphQL.Query>(ctx || RuntimeContext.Synchronous, query, variables);
diff --git a/src/mol-model/structure/model/model.ts b/src/mol-model/structure/model/model.ts
index 22d1ae04e11f64f66543d5d8b0c134c875afe6bb..de0649f49d31dc0f95a416a90f45f387cf04e408 100644
--- a/src/mol-model/structure/model/model.ts
+++ b/src/mol-model/structure/model/model.ts
@@ -23,6 +23,7 @@ import { ModelFormat } from '../../../mol-model-formats/structure/format';
  */
 export interface Model extends Readonly<{
     id: UUID,
+    entryId: string,
     label: string,
 
     /** the name of the entry/file/collection the model is part of */
diff --git a/src/mol-model/structure/structure/properties.ts b/src/mol-model/structure/structure/properties.ts
index 046c32f78fe03fda22f9f4c9b1878bf49550b5d3..5ca9b5caa1bf81fd1592e5cf601683ce53429626 100644
--- a/src/mol-model/structure/structure/properties.ts
+++ b/src/mol-model/structure/structure/properties.ts
@@ -139,6 +139,7 @@ const unit = {
     operator_name: p(l => l.unit.conformation.operator.name),
     model_index: p(l => l.unit.model.modelNum),
     model_label: p(l => l.unit.model.label),
+    model_entry_id: p(l => l.unit.model.entryId),
     hkl: p(l => l.unit.conformation.operator.hkl),
     spgrOp: p(l => l.unit.conformation.operator.spgrOp),
 
diff --git a/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts b/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts
index 91bf463a64fdc79a31f5f6159d49759d1a402a89..0b937d954b18d4cbbd40ae57370310f82bf4f160 100644
--- a/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts
+++ b/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts
@@ -14,13 +14,13 @@ import { PluginBehavior } from '../../../behavior';
 import { ThemeDataContext } from '../../../../../mol-theme/theme';
 import { CustomPropertyRegistry } from '../../../../../mol-model-props/common/custom-property-registry';
 
-export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: boolean }>({
+export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: boolean, showTooltip: boolean }>({
     name: 'pdbe-structure-quality-report-prop',
     category: 'custom-props',
     display: { name: 'PDBe Structure Quality Report' },
-    ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean }> {
+    ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean, showTooltip: boolean }> {
         private attach = StructureQualityReport.createAttachTask(
-            m => `https://www.ebi.ac.uk/pdbe/api/validation/residuewise_outlier_summary/entry/${m.label.toLowerCase()}`,
+            m => `https://www.ebi.ac.uk/pdbe/api/validation/residuewise_outlier_summary/entry/${m.entryId.toLowerCase()}`,
             this.ctx.fetch
         );
 
@@ -32,9 +32,27 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
             attach: this.attach
         }
 
+        private labelPDBeValidation = (loci: Loci): string | undefined => {
+            if (!this.params.showTooltip) return void 0;
+
+            switch (loci.kind) {
+                case 'element-loci':
+                    const e = loci.elements[0];
+                    const u = e.unit;
+                    if (!u.model.customProperties.has(StructureQualityReport.Descriptor)) return void 0;
+
+                    const se = StructureElement.Location.create(u, u.elements[OrderedSet.getAt(e.indices, 0)]);
+                    const issues = StructureQualityReport.getIssues(se);
+                    if (issues.length === 0) return 'PDBe Validation: No Issues';
+                    return `PDBe Validation: ${issues.join(', ')}`;
+
+                default: return void 0;
+            }
+        }
+
         register(): void {
             this.ctx.customModelProperties.register(this.provider);
-            this.ctx.lociLabels.addProvider(labelPDBeValidation);
+            this.ctx.lociLabels.addProvider(this.labelPDBeValidation);
 
             this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('pdbe-structure-quality-report', {
                 label: 'PDBe Structure Quality Report',
@@ -45,37 +63,22 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
             })
         }
 
-        update(p: { autoAttach: boolean }) {
+        update(p: { autoAttach: boolean, showTooltip: boolean }) {
             let updated = this.params.autoAttach !== p.autoAttach
             this.params.autoAttach = p.autoAttach;
+            this.params.showTooltip = p.showTooltip;
             this.provider.defaultSelected = p.autoAttach;
             return updated;
         }
 
         unregister() {
-            console.log('unregister')
             this.ctx.customModelProperties.unregister(StructureQualityReport.Descriptor.name);
-            this.ctx.lociLabels.removeProvider(labelPDBeValidation);
+            this.ctx.lociLabels.removeProvider(this.labelPDBeValidation);
             this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('pdbe-structure-quality-report')
         }
     },
     params: () => ({
-        autoAttach: PD.Boolean(false)
+        autoAttach: PD.Boolean(false),
+        showTooltip: PD.Boolean(true)
     })
-});
-
-function labelPDBeValidation(loci: Loci): string | undefined {
-    switch (loci.kind) {
-        case 'element-loci':
-            const e = loci.elements[0];
-            const u = e.unit;
-            if (!u.model.customProperties.has(StructureQualityReport.Descriptor)) return void 0;
-
-            const se = StructureElement.Location.create(u, u.elements[OrderedSet.getAt(e.indices, 0)]);
-            const issues = StructureQualityReport.getIssues(se);
-            if (issues.length === 0) return 'PDBe Validation: No Issues';
-            return `PDBe Validation: ${issues.join(', ')}`;
-
-        default: return void 0;
-    }
-}
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/src/mol-plugin/index.ts b/src/mol-plugin/index.ts
index 209daad2cf8211815ed338108973b88dfb217af1..5dffcda53e795767023686c367c80c5d3ba919ba 100644
--- a/src/mol-plugin/index.ts
+++ b/src/mol-plugin/index.ts
@@ -66,7 +66,7 @@ export const DefaultPluginSpec: PluginSpec = {
         PluginSpec.Behavior(PluginBehaviors.Camera.FocusLociOnSelect, { minRadius: 8, extraRadius: 4 }),
         // PluginSpec.Behavior(PluginBehaviors.Labels.SceneLabels),
         PluginSpec.Behavior(PluginBehaviors.CustomProps.MolstarSecondaryStructure, { autoAttach: true }),
-        PluginSpec.Behavior(PluginBehaviors.CustomProps.PDBeStructureQualityReport, { autoAttach: true }),
+        PluginSpec.Behavior(PluginBehaviors.CustomProps.PDBeStructureQualityReport, { autoAttach: true, showTooltip: true }),
         PluginSpec.Behavior(PluginBehaviors.CustomProps.RCSBAssemblySymmetry, { autoAttach: true }),
         PluginSpec.Behavior(StructureRepresentationInteraction)
     ],
diff --git a/src/mol-plugin/state/transforms/model.ts b/src/mol-plugin/state/transforms/model.ts
index 6df5fc2fe65abb369cf4b2277eb9cb3fe1c100ba..2b41362937df3b6f08a5f29a2fb9ac4ace2542a7 100644
--- a/src/mol-plugin/state/transforms/model.ts
+++ b/src/mol-plugin/state/transforms/model.ts
@@ -228,12 +228,12 @@ const StructureAssemblyFromModel = PluginStateTransform.BuiltIn({
 
             if (model.symmetry.assemblies.length === 0) {
                 if (id !== 'deposited') {
-                    plugin.log.warn(`Model '${a.data.label}' has no assembly, returning deposited structure.`);
+                    plugin.log.warn(`Model '${a.data.entryId}' has no assembly, returning deposited structure.`);
                 }
             } else {
                 asm = ModelSymmetry.findAssembly(model, id || '');
                 if (!asm) {
-                    plugin.log.warn(`Model '${a.data.label}' has no assembly called '${id}', returning deposited structure.`);
+                    plugin.log.warn(`Model '${a.data.entryId}' has no assembly called '${id}', returning deposited structure.`);
                 }
             }
 
@@ -533,8 +533,12 @@ const CustomModelProperties = PluginStateTransform.BuiltIn({
 });
 async function attachModelProps(model: Model, ctx: PluginContext, taskCtx: RuntimeContext, names: string[]) {
     for (const name of names) {
-        const p = ctx.customModelProperties.get(name);
-        await p.attach(model).runInContext(taskCtx);
+        try {
+            const p = ctx.customModelProperties.get(name);
+            await p.attach(model).runInContext(taskCtx);
+        } catch (e) {
+            ctx.log.warn(`Error attaching model prop '${name}': ${e}`);
+        }
     }
 }
 
@@ -558,8 +562,12 @@ const CustomStructureProperties = PluginStateTransform.BuiltIn({
 });
 async function attachStructureProps(structure: Structure, ctx: PluginContext, taskCtx: RuntimeContext, names: string[]) {
     for (const name of names) {
-        const p = ctx.customStructureProperties.get(name);
-        await p.attach(structure).runInContext(taskCtx);
+        try {
+            const p = ctx.customStructureProperties.get(name);
+            await p.attach(structure).runInContext(taskCtx);
+        } catch (e) {
+            ctx.log.warn(`Error attaching structure prop '${name}': ${e}`);
+        }
     }
 }
 
diff --git a/src/perf-tests/mol-script.ts b/src/perf-tests/mol-script.ts
index 0ff78a678e3ce1b1976e9ff77ca34ec1f0499888..3c9d21c487bd80e08a37f3af752b6e225d1f38a3 100644
--- a/src/perf-tests/mol-script.ts
+++ b/src/perf-tests/mol-script.ts
@@ -69,7 +69,7 @@ export async function testQ() {
 
     await StructureQualityReport.attachFromCifOrApi(structure.models[0], {
         PDBe_apiSourceJson: async model => {
-            const rawData = await fetch(`https://www.ebi.ac.uk/pdbe/api/validation/residuewise_outlier_summary/entry/${model.label.toLowerCase()}`, { timeout: 1500 });
+            const rawData = await fetch(`https://www.ebi.ac.uk/pdbe/api/validation/residuewise_outlier_summary/entry/${model.entryId.toLowerCase()}`, { timeout: 1500 });
             return await rawData.json();
         }
     })
diff --git a/src/servers/model/properties/providers/pdbe.ts b/src/servers/model/properties/providers/pdbe.ts
index 7935d4a49bd1f971f84240e778d32459e61b7fd4..3cdf258176546145ab915d874f5ef5450d6b48c6 100644
--- a/src/servers/model/properties/providers/pdbe.ts
+++ b/src/servers/model/properties/providers/pdbe.ts
@@ -40,14 +40,14 @@ namespace residuewise_outlier_summary {
         // This is for "testing" purposes and should probably only read
         // a single file with the appropriate prop in the "production" version.
         return async (model: Model) => {
-            const key = `${model.label[1]}${model.label[2]}`;
+            const key = `${model.entryId[1]}${model.entryId[2]}`;
             if (!json.has(key)) {
                 const fn = path.join(pathPrefix, `${key}.json`);
                 if (!fs.existsSync(fn)) json.set(key, { });
                 // TODO: use async readFile?
                 else json.set(key, JSON.parse(fs.readFileSync(fn, 'utf8')));
             }
-            return json.get(key)![model.label.toLowerCase()] || { };
+            return json.get(key)![model.entryId.toLowerCase()] || { };
         }
     }
 }
@@ -74,15 +74,15 @@ function apiQueryProvider(urlPrefix: string, cache: any) {
     return async (model: Model) => {
         try {
             if (cache[cacheKey]) return cache[cacheKey];
-            const rawData = await fetchRetry(`${urlPrefix}/${model.label.toLowerCase()}`, 1500, 5);
+            const rawData = await fetchRetry(`${urlPrefix}/${model.entryId.toLowerCase()}`, 1500, 5);
             // TODO: is this ok?
             if (rawData.status !== 200) return { };
-            const json = (await rawData.json())[model.label.toLowerCase()] || { };
+            const json = (await rawData.json())[model.entryId.toLowerCase()] || { };
             cache[cacheKey] = json;
             return json;
         } catch (e) {
             // TODO: handle better
-            ConsoleLogger.warn('Props', `Count not retrieve prop @${`${urlPrefix}/${model.label.toLowerCase()}`}`);
+            ConsoleLogger.warn('Props', `Count not retrieve prop @${`${urlPrefix}/${model.entryId.toLowerCase()}`}`);
             return { };
         }
     }
diff --git a/src/servers/model/server/query.ts b/src/servers/model/server/query.ts
index 9bbcf807c932e4ba80520f9f3dc1ec065a77e57c..726e74a96aeb33b3197c3de46718f388025abc6a 100644
--- a/src/servers/model/server/query.ts
+++ b/src/servers/model/server/query.ts
@@ -72,7 +72,7 @@ export async function resolveJob(job: Job): Promise<CifWriter.Encoder<any>> {
         ConsoleLogger.logId(job.id, 'Query', 'Query finished.');
 
         perf.start('encode');
-        encoder.startDataBlock(sourceStructures[0].models[0].label.toUpperCase());
+        encoder.startDataBlock(sourceStructures[0].models[0].entryId.toUpperCase());
         encoder.writeCategory(_model_server_result, job);
         encoder.writeCategory(_model_server_params, job);